【发布时间】:2013-09-18 22:41:11
【问题描述】:
我在 Rails 4 中有以下模型,带有一个简单的 has_many :through 关联:
class Model < ActiveRecord::Base
has_many :model_options
has_many :options, through: :model_options
end
class Option < ActiveRecord::Base
has_many :model_options
has_many :models, through: :model_options
end
class ModelOption < ActiveRecord::Base
belongs_to :model
belongs_to :option
end
我希望能够迭代模型实例的选项:
model = Model.find.first
model.options.each {}
并访问连接表上的属性。
在 Rails 3 中你可以这样做:
class Model < ActiveRecord::Base
has_many :model_options
has_many :options, through: :model_options , select: 'options.*, model_options.*'
end
但 select: 已弃用,这会产生弃用警告。
也就是说,生成的SQL包含链接表数据:
SELECT options.*, model_options.* FROM "options"
INNER JOIN "model_options" ON "options"."id" = "model_options"."option_id"
WHERE "model_options"."model_id" = $1 ORDER BY "options".name ASC [["model_id", 1]]
但是AR从model.options返回的集合删除了链接表数据。
为了消除 Rails 4 中的弃用警告,并且仍然产生相同的 SQL,我这样做了:
class Model < ActiveRecord::Base
has_many :model_options
has_many :options, -> { select('options.*, model_options.*') }, through: :model_options
end
所以,查询是正确的,但我正在努力寻找访问链接表数据的正确方法。
我尝试了各种方法:
model options
model.options.joins(:model_options)
model.options.select('options.*, model_options.*')
model.model_options.joins(:option)
...
不包括连接表数据。
谢谢。
【问题讨论】:
-
ModelOption 模型在两个 id 之外还有什么作用吗?
-
是的,ModelOption 上面有很多属性。例如,价格,其中一个选项的价格会因型号而异。
-
我也有同样的问题。你是怎么解决的?
-
@Karsten,我发现在您指定之后,连接表属性可以作为
model.price透明访问(其中price作为ModelOption 的属性)has_many ... select()声明以包含它们。
标签: ruby-on-rails activerecord