In Rails, what is the inverse of update_attributes!
?
In other words, what maps a record to an attributes hash that would recreate that record and all of it children records?
The answer is not ActiveRecord.attributes
as that will not recurse into child object.
To clarify if you have the following:
class Foo < ActiveRecord::Base
has_many :bars
accepts_nested_attributes_for :bars
end
Then you can pass an hash like
{"name" => "a foo", "bars_attributes" => [{"name" => "a bar} ...]}
to update_attributes
. But it's not clear how to easily generate such a hash programatically for this purpose.
EDIT:
As I have mentioned in a comment, I can do something like:foo.as_json(:include => :bars)
but I wanted a solution that uses the accepts_nested_attributes_for :bars
declaration to avoid having to explicitly include associations.
Not sure how that would be the "inverse", but while Rails might not "have the answer" per-see, there is nothing stopping you from traversing through an object and creating this VERY efficiently.
Something to get you started:
http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html#method-i-accepts_nested_attributes_for
You'll notice in the accepts_nested_attributes_for
method, rails sets a hash for all models nested, in nested_attributes_options
. So we can use that to get these nested associations, to populate this new hash.
def to_nested_hash
nested_hash = self.attributes.delete_if {|key, value| [:id, :created_at, :deleted_at].include? key.to_sym } # And any other attributes you don't want
associations = self.nested_attributes_options.keys
associations.each do |association|
key = "#{association}_attributes"
nested_hash[key] = []
self.send(association).find_each do |child|
nested_hash[key] << child.attributes.delete_if {|key, value| [:id, :created_at, :deleted_at].include? key.to_sym }
end
end
return nested_hash
end
Using your example above:
foo.as_json(:include => foo.nested_attributes_options.keys)
One thing to note, this won't give you the bars_attributes
where my first suggestions will. (neither will serializable_hash
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With