每个用户has_many:通知,每个通知has_many:注释,每个类通知。每个通知/评论has_one:supernotice,即发表评论的通知。
尝试提交评论后,我收到此错误消息:undefined method 'id' for "#<Notice:0x0000010eed6958>":String
。为什么Rails认为我的Notice
是String
?
notices_controller.rb:
def create
@notice = user.notices.build(notice_params)
if @notice.save
if !params[:notice][:commentee].nil?
@notice.create_comment(params[:notice][:commentee])
end
end
end
private
def notice_params
params.require(:notice).permit(:content, :comentee)
end
notice.rb:
belongs_to :user
has_one :active_comment_relationship, class_name: "Commentrelationship", foreign_key: "commenter_id", dependent: :destroy
has_one :supernotice, through: :active_comment_relationship, source: :commentee
def create_comment(other_notice)
active_comment_relationship.create(commentee_id: other_notice.id)
end
在_notice.html.erb中提交有关通知的评论:
<%= form_tag( {controller: "notices", action: "create"}, method: "post", id: "comment_form" ) do %>
<%= hidden_field_tag :callsign, @user.callsign %>
<%= hidden_field_tag "notice[commentee]", notice %>
<%= text_area_tag "notice[content]", '', id: "commentField" %>
<%= submit_tag "Reply" %>
<% end %>
服务器日志:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"...", "callsign"=>"bazzer", "notice"=>{"commentee"=>"#<Notice:0x00000110a49140>", "content"=>"Hello there."}, "commit"=>"Reply"}
答案 0 :(得分:0)
因为它只能以表单值的形式呈现为字符串。反复序列化也不会对你有任何好处。显而易见的选择是传递该通知的id
并进行查找。但我个人更喜欢不同的做法。
如果评论张贴在该通知的notice_id
页面上,您可能根本不需要从表单中传递show
::id
已经是路线的一部分那里。如果您创建嵌套资源:
resources :notices do
resources :comments
end
...你的评论&#39;路线贴在通知的顶部&#39;路线。您可以为注释创建控制器,并且可以使用以下路由访问注释集合:
notices_comments_path(@notice)
# => /notices/42/comments
因此,当您将评论发布到上述格式的网址时,您必须传递根本没有隐藏的参数:
params[:note_id]
查找callsign
可以在控制器层的current_user
上查找(使用Devise或Sorcery)这样做的原因是因为隐藏的输入隐藏在视线之外,而不是来自开发人员工具,并且因此被篡改。为了解决这个问题,在控制器中使用额外的检查是很诱人的,但是为什么如果控制器能够自己分配它们呢?
反模式警告:不要过多地嵌套资源。 2级是可以的,3级是关注的,4级是可怕的。