Ruby on Rails - 如何在创建时处理belongs_to multiple

时间:2017-01-11 15:40:04

标签: ruby-on-rails ruby devise

我正在尝试创建一个属于多个模型的评论,但我不确定将它分配给两者的最佳做法。

class Comment < ApplicationRecord
    validates :message, :presence => true
    belongs_to :user
    belongs_to :discussion
end

在讨论中创建注释时,我遇到错误“讨论必须存在”。

我正在使用Devise,因此我使用current_user并构建一个Comment以将它与它们对齐,但我不确定如何将它指向两者。这似乎有效,但似乎非常hacky。

def create
    @comment = current_user.comments.build(comment_params)
    @comment.discussion_id = params[:discussion_id]
    ...
end

最佳做法是什么?

4 个答案:

答案 0 :(得分:3)

无论你怎么做,你都需要设置discussion_id或让它出现在comment_params

对你来说,这看起来不那么神奇了吗?

def create
    comment_params.merge(discussion_id: params[:discussion_id])
    @comment = current_user.comments.build(comment_params)
    ...
end

答案 1 :(得分:3)

我会将:discussion_id添加到comment_params方法:

def create
  @comment = current_user.comments.build(comment_params)
  ...
end

private

def comment_params
  params.require(:comment)
        .permit(...)
        .merge(discussion_id: params.require(:discussion_id))
end

您可以将build与块一起使用:

def create
  @comment = current_user.comments.build(comment_params) { |comment| 
    comment.discussion_id = params[:discussion_id] 
  }
  # ...
end

答案 2 :(得分:2)

您可以在块中传递其他参数

params = ActionController::Parameters.new({
  comment: {
    name: 'Francesco',
    body:  'Text'
  }
})

comment_params = params.require(:comment).permit(:name, :body)

def create
  @comment = current_user.comments.build(comment_params) do |comment|
    comment.discussion_id = params[:discussion_id]
  end
end

答案 3 :(得分:1)

创建与多个实体关联的实体时,需要记住几件事。

关于最佳做法的问题。我想在此强调一个交互器的用法:

# xx_controller.rb
def create
  success = CreateComment.call(params)
  if success
     ....
  else
     ....
  end
end


# ../../create_comment.rb
# pseudocode
class CreateComment
  def call(params)
    validate your params # check if nothing is missing, the discussion exists and you have a user
    build_and_save_your_comment
    return_your_result_object # return a tuple or a result or whatever you need in order to handle errors and success cases...
  end
end

通过这种方法,您可以在控制器中保持可读性,并且可以专注于在专门的地方创建评论的重要性。