tengo tres modelos ActiveRecord: Socio, MembershipChannel (que es un modelo STI, heredando de Canal) y ChannelMembership (yo no era responsable de nombrar estos modelos ...)¿Por qué mi has_many a través de un registro asociado (a veces) de solo lectura?
Cuando cargo un ChannelMembership través de la asociación de socios, que a veces (!) terminan con un registro de solo lectura. Esto está en Rails 3.0.9. El mismo código no se comportó de esta manera en 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
¿Por qué es readonly?
cierto cuando first
se llama en la asociación, pero no en la relación de limit
?
Entiendo que readonly
se activa si utilizo fragmentos de SQL para encontrar un registro, pero este no es el caso aquí. Es simplemente una simple has_many a través de la asociación. La única complicación es que se une a un modelo de STI. Además, mirando el SQL generado de los dos últimos ejemplos, ¡son idénticos!
Puedo obtener el comportamiento que deseo especificando :readonly => false
en la asociación, pero quiero entender qué está pasando.
No hay ámbitos predeterminados en Channel, MembershipChannel o ChannelMembership. Aquí está la declaración de asociación sobre el Partner:
class Partner
has_many :membership_channels
has_many :channel_memberships, :through => :membership_channels
end
Aquí está el código SQL generado a partir de los registros de mi:
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í, creo que este sería un buen momento para hurgar en AR y AREL. He querido aprender cómo orientarme por la fuente de los raíles, de todos modos. –