我有一個用戶存儲在我想添加爲評論所有者的會話中。我不想爲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
值是必要的。