我有一个用户存储在我想添加为评论所有者的会话中。我不想为user_id隐藏字段,而是在将注释保存到控制器之前添加用户。Ruby on Rails - 将父对象添加到子对象?
这样做的最好方法是什么?
@comment = @post.comments.create(params[:comment])
谢谢。
我有一个用户存储在我想添加为评论所有者的会话中。我不想为user_id隐藏字段,而是在将注释保存到控制器之前添加用户。Ruby on Rails - 将父对象添加到子对象?
这样做的最好方法是什么?
@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
此方法更自动,但以透明度为代价,可能使您的单元测试环境复杂化。
第三种方法是在参数合并在建立来电:
@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
值是必要的。