Ho tre modelli ActiveRecord: Partner, MembershipChannel (che è un modello di STI, che eredita da Channel) e ChannelMembership (non ero responsabile per la denominazione di questi modelli ...)Perché il mio has_many è associato al record (a volte) di sola lettura?
quando carico un ChannelMembership attraverso l'associazione partner, mi a volte (!) finisce con una registrazione di sola lettura. Questo è in Rails 3.0.9. Lo stesso codice non si comporta in questo modo in 2.3.11.
> p = Partner.first
> p.channel_memberships.map(&:readonly?)
# => [false, false, false, false, false, false]
> p.reload.channel_memberships.limit(1).first.readonly?
# => false
> p.reload.channel_memberships.first.readonly?
# => true
Perché readonly?
vero quando first
viene chiamato l'associazione, ma non sulla relazione da limit
?
Capisco che readonly
venga attivato se utilizzo frammenti SQL durante la ricerca di un record, ma questo non è il caso qui. È solo un semplice has_many attraverso l'associazione. L'unica cosa che complica è che si unisce a un modello STI. Cosa c'è di più, guardando l'SQL generato dagli ultimi due esempi, sono identici!
Posso ottenere il comportamento desiderato specificando :readonly => false
sull'associazione, ma voglio capire cosa sta succedendo.
Non ci sono ambiti di default su Canale, MembershipChannel o ChannelMembership. Ecco la dichiarazione di associazione in merito Partner:
class Partner
has_many :membership_channels
has_many :channel_memberships, :through => :membership_channels
end
Ecco l'SQL generato da miei log:
Partner Load (0.4ms) SELECT "partners".* FROM "partners" LIMIT 1
ChannelMembership Load (0.7ms) SELECT "channel_memberships".* FROM "channel_memberships" INNER JOIN "channels" ON "channel_memberships".channel_id = "channels".id WHERE (("channels".partner_id = 2) AND (("channels"."type" = 'MembershipChannel')))
Partner Load (0.5ms) SELECT "partners".* FROM "partners" WHERE "partners"."id" = 2 LIMIT 1
ChannelMembership Load (1.0ms) SELECT "channel_memberships".* FROM "channel_memberships" INNER JOIN "channels" ON "channel_memberships".channel_id = "channels".id WHERE (("channels".partner_id = 2) AND (("channels"."type" = 'MembershipChannel'))) LIMIT 1
Partner Load (0.4ms) SELECT "partners".* FROM "partners" WHERE "partners"."id" = 2 LIMIT 1
ChannelMembership Load (0.6ms) SELECT "channel_memberships".* FROM "channel_memberships" INNER JOIN "channels" ON "channel_memberships".channel_id = "channels".id WHERE (("channels".partner_id = 2) AND (("channels"."type" = 'MembershipChannel'))) LIMIT 1
Sì, penso che questo sarebbe un buon momento per scavare in AR e AREL. In ogni caso, intendevo imparare come orientarmi nella fonte dei binari. –