1

我有一个用户存储在我想添加为评论所有者的会话中。我不想为 user_id 设置一个隐藏字段,而是想在评论保存在控制器中之前添加用户。

最好的方法是什么?

@comment = @post.comments.create(params[:comment])

谢谢。

4

2 回答 2

2

有一些策略效果很好。您可以在控制器中调用,将用户钉在创建的评论上:

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])
于 2010-01-18T20:04:41.917 回答
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值。

于 2010-01-18T20:04:53.550 回答