我有一个用户存储在会话中,我想将其添加为评论的所有者。我没有为user_id设置隐藏字段,而是在评论保存在控制器中之前添加用户。
最好的方法是什么?
@comment = @post.comments.create(params[:comment])
感谢。
答案 0 :(得分:1)
有一些策略运作得相当好。您可以在控制器中调用将用户钉在已创建的注释上:
def create
@comment = @post.comments.build(params[:comment])
@comment.user = session_user
@comment.save!
redirect_to(post_path(@post))
rescue ActiveRecord::RecordInvalid
# Take appropriate action, such as show comment create form
render(:action => 'new')
end
另一种方法是使用类似model_helper(http://github.com/theworkinggroup/model_helper/)的东西来提供对模型环境中控制器属性的访问:
class ApplicationController < ActionController::Base
# Makes the session_user method callable from the ActiveRecord context.
model_helper :session_user
end
class Comment < ActiveRecord::Base
before_validation :assign_session_user
protected
def assign_session_user
if (self.user.blank?)
self.user = session_user
end
end
end
这种方法更自动,但代价是透明,可能会使您的单元测试环境复杂化。
第三种方法是在创建调用中合并参数:
@comment = @post.comments.build((params[:comment] || { }).merge(:user => session_user))
如果您的模型的某些属性受到保护,这样做的缺点是效果不佳,因为它们可能应该在任何生产环境中。
另一个技巧是创建一个有助于为您构建内容的类方法:
class Comment < ActiveRecord::Base
def self.create_for_user(user, params)
created = new(params)
created.user = user
created.save
created
end
end
这是在关系上调用的,并且将构建在正确的范围内:
@comment = @post.comments.create_for_user(session_user, params[:comment])
答案 1 :(得分:1)
首先,出于安全原因,您可能希望保护评论的user_id
属性,因此您的模型中应该包含以下内容:
attr_protected :user_id
或者,使用attr_accessible
并列出可以通过质量分配设置的所有属性(即Comment.create(...)
或@comment.update_attributes(...)
)。然后,因为你必须通过赋值来分配,你的控制器将如下所示:
@comment = @post.comments.new(params[:comment])
@comment.user_id = current_user.id
@comment.save
它不是那么光滑,但是有必要让某人无法提交假的user_id
值。