在我的rails 应用程序中,我有一个views/questions/show.html.erb 页面,除了预期的@question 变量之外,它还可以访问@answers 变量来显示特定问题的所有答案。
在显示特定问题的所有答案的循环内部,我希望显示一个区域供用户评论(在答案而不是问题上),所以我创建了一个评论部分,其中遵循另一个 SO 的建议答案,我创建了一个“本地”哈希来传递变量。在评论控制器的创建操作中,我希望能够访问答案(评论属于答案)和问题(其中 has_many :answers),所以我将答案和问题 id 传递到部分中,就像这样
<% for answer in @answers %>
....(code ommitted)
<%= render :partial => 'comments/form', :locals => { :answer_id => answer.id, :question_id => @question.id } %>
...(code ommitted)
<% end %>
我通过评论部分中的隐藏字段传递 answer_id 和 question_id 像这样
<%= simple_form_for @comment do |f| %>
<%= f.input :content, as: :text, label: 'comment'%>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= f.hidden_field :answer_id, :value => answer_id %>
<%= f.hidden_field :question_id, :value => question_id %>
<%= f.button :submit %>
<% end %>
在评论控制器的创建动作中,我这样做
def create
@question = Question.find(params[:comment][:question_id])
@answer = Answer.find(params[:comment][:answer_id])
@comment = @answer.comments.build(params[:comment])
if @comment.save
flash[:notice] = "Successfully created comment"
redirect_to root_path
# redirect_to question_answers_path(@question) (will eventually want to redirect to the question)
else
render :action => 'new'
end
end
第一个问题,我觉得我不得不通过以下方式提取问题ID(和答案ID)做了一些尴尬的事情
@question = Question.find(params[:comment][:question_id])
但是,这些是提交我的表单后可用的参数
Parameters: {"utf8"=>"✓", "authenticity_token"=>"VtogfCsI137lbk2l64RXtrfRn/+Rt1/jM8pfDVY29gM=", "comment"=>{"content"=>"test", "user_id"=>"12", "answer_id"=>"25", "question_id"=>"22"}, "commit"=>"Create Comment"}
所以我必须像这样挖出question_idparams[:comment][:question_id]
第二个更具挑战性的问题(对我来说具有挑战性)是 Rails 告诉我
Can't mass-assign protected attributes: question_id
我没有理由将 question_id 存储在评论模型上,所以我没有在数据库中为它创建一个列。但是,当我这样做时
@comment = @answer.comments.build(params[:comment])
由于 question_id 是 :comment 中的参数之一(我在表单中为其设置了隐藏字段),Rails 正试图将其保存在评论表中。但是,我真正想要在 comments_controller.rb 的创建操作中访问问题的唯一原因是在保存后使用它重定向回问题。
你能建议我能做些什么来解决这个问题吗?我觉得因为我没有太多使用 Rails 的经验,所以我做的每件事都很尴尬,这可能是它不起作用的原因。我想解决这个问题的简单方法是在评论模型中添加一个 question_id 列,但是它们之间没有“关联”,所以我认为这是错误的解决方案。