【发布时间】:2011-10-30 11:48:11
【问题描述】:
我有三个 ActiveRecord 模型:Partner、MembershipChannel(这是一个 STI 模型,继承自 Channel)和 ChannelMembership(我不负责命名这些模型……)
当我通过合作伙伴关联加载 ChannelMembership 时,有时(!)会得到一个只读记录。这是在 Rails 3.0.9 中。相同的代码在 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
为什么在关联上调用first 时readonly? 为真,而不是在来自limit 的关系上调用?
我知道如果我在查找记录时使用 SQL 片段会触发readonly,但这里不是这种情况。它只是一个简单的 has_many 通过关联。唯一复杂的是它加入了 STI 模型。更何况,看看最后两个例子生成的SQL,它们是一样的!
我可以通过在关联上指定:readonly => false 来获得我想要的行为,但我想了解发生了什么。
Channel、MembershipChannel 或 ChannelMembership 上没有默认范围。以下是关于 Partner 的关联声明:
class Partner
has_many :membership_channels
has_many :channel_memberships, :through => :membership_channels
end
这是从我的日志中生成的 SQL:
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
【问题讨论】:
标签: ruby ruby-on-rails-3 activerecord has-many-through