Ho un paio di classi:: autosave ignorato su has_many relation - cosa mi manca?
class Collection < ActiveRecord::Base
has_many :items, autosave: true
end
class Item < ActiveRecord::Base
belongs_to :collection
end
Dal docs:
Quando: salvataggio automatico è vero tutti i bambini sono salvate, non importa se sono nuovi record:
Ma quando aggiorno uno Item
e salvo il suo genitore Collection
, gli attributi rialzati dello Item
non vengono salvati:
> c = Collection.first
=> #<Collection id: 1, name: "collection", created_at: "2012-07-23 00:00:10", updated_at: "2012-07-23 00:00:10">
> i = c.items.first
=> #<Item id: 1, collection_id: 1, name: "item1", created_at: "2012-07-23 00:00:25", updated_at: "2012-07-23 00:00:25">
> i.name = 'new name'
=> "new name"
> c.save
=> true
> Collection.first.items
=> [#<Item id: 1, collection_id: 1, name: "item1", created_at: "2012-07-23 00:00:25", updated_at: "2012-07-23 00:00:25">]
Quindi, cosa mi manca?
Sto usando Rails 3.2.5 e Ruby 1.9.2.
Così ho fatto un po 'scavare circa nella fonte di ActiveRecord. Siamo in grado di entrare in possesso di association salvataggio automatico c
s':
> c.class.reflect_on_all_autosave_associations
=> [#<ActiveRecord::Reflection::AssociationReflection:0x007fece57b3bd8 @macro=:has_many, @name=:items, @options={:autosave=>true, :extend=>[]}, @active_record=Collection(id: integer, name: string, created_at: datetime, updated_at: datetime), @plural_name="items", @collection=true, @class_name="Item", @klass=Item(id: integer, collection_id: integer, name: string, created_at: datetime, updated_at: datetime), @foreign_key="collection_id", @active_record_primary_key="id", @type=nil>]
Credo che questo dimostra che l'associazione è stata costituita per il salvataggio automatico.
Possiamo quindi ottenere l'istanza dell'associazione corrispondente a c
:
> a = c.send :association_instance_get, :items
=> #<ActiveRecord::Associations::HasManyAssociation:0x007fece738e920 @target=[#<Item id: 1, collection_id: 1, name: "item1", created_at: "2012-07-23 00:00:25", updated_at: "2012-07-23 00:00:25">], @reflection=#<ActiveRecord::Reflection::AssociationReflection:0x007fece57b3bd8 @macro=:has_many, @name=:items, @options={:autosave=>true, :extend=>[]}, @active_record=Collection(id: integer, name: string, created_at: datetime, updated_at: datetime), @plural_name="items", @collection=true, @class_name="Item", @klass=Item(id: integer, collection_id: integer, name: string, created_at: datetime, updated_at: datetime), @foreign_key="collection_id", @active_record_primary_key="id", @type=nil>, @owner=#<Collection id: 1, name: "collection", created_at: "2012-07-23 00:00:10", updated_at: "2012-07-23 00:00:10">, @updated=false, @loaded=true, @association_scope=[#<Item id: 1, collection_id: 1, name: "item1", created_at: "2012-07-23 00:00:25", updated_at: "2012-07-23 00:00:25">], @proxy=[#<Item id: 1, collection_id: 1, name: "item1", created_at: "2012-07-23 00:00:25", updated_at: "2012-07-23 00:00:25">], @stale_state=nil>
Possiamo quindi trovare gli oggetti reali che sono associati con questa associazione:
> a.target
=> [#<Item id: 1, collection_id: 1, name: "item1", created_at: "2012-07-23 00:00:25", updated_at: "2012-07-23 00:00:25">]
L'oggetto trovato qui fa non ho aggiornamenti che ho fatto prima.
Grazie. E qui ho pensato .first == [0] – Arcolye
Normalmente lo è. Questa differenza è causata dal fatto che Rails trasforma utilmente #primo in predicati SQL. Puoi vedere Ruby # prima fonte C qui: http://ruby-doc.org/core-2.1.3/Enumerable.html#method-i-first e la relazione di Ralis qui: https://github.com/rails/ rotaie/blob/f244d8f53279efd755e7299418b408641baedc9c/ActiveRecord/lib/active_record/relazione/finder_methods.rb # L128 – bronson