Order of params stops *_attributes= from working
So I've implemented a hack and I want to know what the "proper" way is to do it.
The issue is that I have an *_attributes=()
method that uses an instance variable. The reason this is a problem is that at the time the method is called, that instance variable hasn't been set. Here is the 开发者_如何学运维method in question:
def proposed_times_attributes=(attributes)
attributes.each do |key,value|
value[:timezone] = timezone
end
assign_nested_attributes_for_collection_association(:proposed_times, attributes)
end
The timezone is in the params hash after proposed_times_attributes
. Therefore my hack is to delete it from params, then add it back, thus moving it to the end of the line.
def create
p = params[:consultation]
a = p.delete(:proposed_times_attributes)
p[:proposed_times_attributes] = a
@consultation = current_user.advised_consultations.new(p)
...
end
What is the proper way that I should be doing this?
new()
calls load()
where the loop is that goes through each key/value pair.
Thankfully I'm using Ruby 1.9.2 which keeps the order, but it would be nice to know how to do this so that it wouldn't depend on this fact.
If the next operation after new
will always be a save
operation, you can store the attributes in an accessor, and use a before_validation
callback to operate on them as you wish.
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
Now in your controller you simply have:
def create
@consultation = current_user.advised_consultations.new(params[:consultation])
...
end
If you wish to do other operations before calling save
, then pulling out the param as you did in your example, then passing it to an appropriate method after calling new
would be the way to go.
精彩评论