Howdy -
Reading around, it looks like consume! is intended to just make / update instances of objects but not to save them.
Basing this statement on:
I thought a lot about the #consume! semantic and I decided it would be
best to just do the setup process (e.g. filling the object with
incoming data). Everything else, like saving and stuff is up to the
user. That was to save us from having to write adapters for DM, AR,
Sequel etc.
and the roar-rails README:
The consume! call will roughly do the following.
singer.
extend(SingerRepresenter)
from_json(request.body)
But yesterday when I was consuming JSON representing a model and its contained collection of new model instances, I noticed that the model instances in the child collection were getting saved to database (using activerecord).
It appears that this is because at some point in representable there is a call to set the has_many relation to the collection of newly instantiated objects, and in ActiveRecord when you have "aModel" persisted in the DB and then call aModel#collection=(array of instances) , the instances added to the collection are saved to the DB:
(http://guides.rubyonrails.org/association_basics.html)
4.3.4 When are Objects Saved?
When you assign an object to a has_many association, that object is automatically saved (in order to update its foreign key). If you assign multiple objects in one statement, then they are all saved.
...
If you want to assign an object to a has_many association without saving the object, use the collection.build method
Is this behavior expected or unexpected? If unexpected but not easily fixable, might want to point it out in the README -- I had been working under the assumption that consume! wouldn't alter my DB.
Ideas on a workaround? If I open up some attr_protected fields I think I can use a setter in my collection definition:
class MyModel < ActiveRecord::Base
has_many :items
with a decorator representer having the following collection:
collection :items
...
setter: lambda do |value, *|
items_attributes = value.collect{|v| v.attributes}
items.build(items_attributes)} # build wants attributes not objects
end
Other thoughts? Addressable in roar-rails or representable?
Thanks - JP