所以我实施了一个黑客,我想知道什么是"正确"的方法。
问题是我有一个使用实例变量的*_attributes=()
方法。这是一个问题的原因是,在调用该方法时,尚未设置该实例变量。这是有问题的方法:
def proposed_times_attributes=(attributes)
attributes.each do |key,value|
value[:timezone] = timezone
end
assign_nested_attributes_for_collection_association(:proposed_times, attributes)
end
时区在 proposed_times_attributes
之后的参数哈希中。因此,我的技巧是从参数中删除它,然后将其添加回来,从而将其移动到行尾。
def create
p = params[:consultation]
a = p.delete(:proposed_times_attributes)
p[:proposed_times_attributes] = a
@consultation = current_user.advised_consultations.new(p)
...
end
我应该这样做的正确方法是什么?
new()
调用load()
遍历每个键/值对的循环所在位置。
值得庆幸的是,我使用的是 Ruby 1.9.2 来保持顺序,但很高兴知道如何做到这一点,这样它就不会依赖于这个事实。
如果new
之后的下一个操作始终是save
操作,则可以将属性存储在访问器中,并根据需要使用before_validation
回调对它们进行操作。
class Consultations < ActiveRecord::Base
attr_accessor :proposed_times_attributes
before_validation :assign_proposed_times
def assign_proposed_times
proposed_times_attributes.each do |key,value|
value[:timezone] = timezone
end
assign_nested_attributes_for_collection_association(:proposed_times, attributes)
end
end
现在,在您的控制器中,您只需拥有:
def create
@consultation = current_user.advised_consultations.new(params[:consultation])
...
end
如果您希望在调用 save
之前执行其他操作,那么像在示例中所做的那样拉出参数,然后在调用 new
后将其传递给适当的方法将是要走的路。