2010-01-18 68 views
1

我有一个用户存储在我想添加为评论所有者的会话中。我不想为user_id隐藏字段,而是在将注释保存到控制器之前添加用户。Ruby on Rails - 将父对象添加到子对象?

这样做的最好方法是什么?

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

谢谢。

回答

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

首先,对于安全的原因,你可能想要保护评论的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值是必要的。