在rails中创建回复关联

时间:2015-11-08 18:43:52

标签: ruby-on-rails

所以我正在开发一个用户可以创建主题的项目,用户可以回复它们。我在确定如何关联user_id和topic_id并在回复时存储它们时遇到了很多麻烦。

Model Reply.rb

class Reply < ActiveRecord::Base
  belongs_to :topic
  belongs_to :user
end

Controller replies_controller.rb

class RepliesController < ApplicationController
  before_action :authenticate_user!, except: [:show]

  def show
  end

  def new
    @topic = Topic.find(params[:id])
    @reply = @topic.replies.build
  end

  def create
    @reply = Reply.new(reply_params)
    @reply.user_id = current_user.id
    @reply.topic_id = Topic.find(params[:id])

    if @reply.save
      flash[:notice] = 'Reply Success!'
      redirect_to @reply
    else
      flash[:notice] = 'Response could not be made!'
      render 'new'
    end
  end

  def edit
  end

  def update
    if @reply.update(reply_params)
      flash[:notice] = 'Response updated!'
      redirect_to @reply
    else
      flash[:notice] = 'Response could not be updated!'
      redirect 'edit'
    end
  end

  def destroy
    @reply.destroy
    flash[:notice] = 'Response removed!'
    redirect_to replies_topic
  end

  private

  def reply_params
    params.require(:reply).permit(:details, :user_id, :topic_id)
  end

  # Verify so people won't be able to delete/edit other peoples replies
  def reply_owner
    unless @reply.user_id == current_user.id
      flash[:notice] = 'Access denied. You are not the owner of this response.'
      redirect_to stories_path
    end
  end
end

Controller topics_controller.rb

class TopicsController < ApplicationController
  before_action :set_topic, only: [:show, :edit, :update, :destroy]

  def index
    @topics = Topic.all
  end

  def show
    @topic = Topic.find(params[:id])
    @reply = @topic.replies
  end

  def new
    @topics = Topic.new
  end

  def create
    # Need system that will check if a names are similar.
    # Similar to how stackoverflow does asking questions

    @topics = Topic.new(topic_params)

    if @topics.save
      flash[:notice] = "Topic created!"
      redirect_to @topics
    else
      flash[:alert] = "Topic is already created"
      redirect 'new'
    end
  end

  def edit
  end

  def update
    if @topics.update(topic_params)
      flash[:notice] = 'Topic Updated!'
      redirect_to @topics
    else
      flash[:alert] = 'Topic could not be updated'
      render 'edit'
    end
  end

  def destroy
    @topics.destroy
    flash[:notice] = 'Topic has been removed.'
    redirect_to topics_path
  end

  private

  def topic_params
    params.require(:topic).permit(:name)
  end

  def set_topic
    @topics = Topic.find(params[:id])
  rescue ActiveRecord::RecordNotFound
    flash[:alert] = 'The story you are looking for could not be
                    found. Maybe contact the author to check if they have a copy?'
    redirect_to topics_path
  end
end

查看主题/ show

<p><%= link_to "Reply", new_reply_path(topic_id: @topic.id ) %></p>

路由routes.rb

Rails.application.routes.draw do

  get 'users/show'

  root 'static_pages#home'
  get 'about' => 'static_pages#about'

  devise_for :users, :skip => [:sessions]
  as :user do
    get 'login' => 'devise/sessions#new', :as => :new_user_session
    post 'login' => 'devise/sessions#create', :as => :user_session
    delete 'logout' => 'devise/sessions#destroy', :as => :destroy_user_session
  end

  resources :users

  resources :stories

  resources :topics
  resources :replies

end

1 个答案:

答案 0 :(得分:0)

为什么将replies视为单独的数据集?您最好将所有topics保持在一个model下,您可以使用acts_as_tree等层次结构宝石将其分开:

#app/models/topic.rb
class Topic < ActiveRecord::Base
   acts_as_tree #-> requires you put a "parent_id" column in your topics model
end

这样,您就可以使用以下内容:

#config/routes.rb
resources :topics do
   resources :replies, controller: :topics, only: [:create, :destroy] #-> url.com/topics/:topic_id/replies
end

这样,您就可以使用以下内容:

#app/controllers/topics_controller.rb
class TopicsController < ApplicationController
   def show
     @topic = Topic.find params[:id]
     @reply = @topic.children.new
   end

   def create
     @topic = Topic.new topic_params
     @topic.save
   end

   private

   def topic_params 
      params.require(:topic).permit(:topic, :params, :parent_id)
   end
end

#app/views/topics/show.html.erb
<%= @topic.name %>
<%= render "reply", collection: @topic.children, as: :reply if @topic.children.any? %> #-> these are your replies
<%= render "new_reply" %>

#app/views/topics/_reply.html.erb
<%= reply.title %>

#app/views/topics/_new_reply.html.erb
<%= form_for @reply do |f| %>
   <%= f.text_field :topic
   <%= f.submit %>
<% end %>

这将允许您为每个回复创建新的主题记录,从而无需Reply模型。