我有一个用户存储在我想添加为评论所有者的会话中。我不想为 user_id 设置一个隐藏字段,而是想在评论保存在控制器中之前添加用户。
最好的方法是什么?
@comment = @post.comments.create(params[:comment])
谢谢。
我有一个用户存储在我想添加为评论所有者的会话中。我不想为 user_id 设置一个隐藏字段,而是想在评论保存在控制器中之前添加用户。
最好的方法是什么?
@comment = @post.comments.create(params[:comment])
谢谢。
有一些策略效果很好。您可以在控制器中调用,将用户钉在创建的评论上:
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
这种方法更加自动化,但代价是透明度和可能使您的单元测试环境复杂化。
第三种方法是在 create 调用中合并参数:
@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])
首先,出于安全原因,您可能希望保护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
值。