2010-01-18 69 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值是必要的。