此github gist中提供了一个自运行模板,其中包含所有要自行测试的模型 - 运行它并触发错误。
为了使其可视化,结构如下所示:
Colors
|n|
|:|
|1| -----
Houses n:n Conditions
|n| -----
|:|
|1|
People
从空白数据库开始,我创建了一些测试数据(控制台命令,省略了返回值以保持清晰):
irb(main):001:0> Condition.create(condition: :damaged)
irb(main):002:0> house = House.create(conditions: [Condition.first])
irb(main):003:0> person = Person.create
irb(main):004:0> house.person = person
irb(main):005:0> house.save
所以现在我有一些测试数据。让我们检索一下这个人的房子(根据定义,这只是受损房屋):
irb(main):006:0> person.damaged_houses
House Load (0.2ms)
SELECT "houses".* FROM "houses"
INNER JOIN "conditions_houses" ON "conditions_houses"."house_id" = "houses"."id"
INNER JOIN "conditions" ON "conditions"."id" = "conditions_houses"."condition_id"
WHERE "houses"."person_id" = ? AND "conditions"."condition" = 'damaged'
[["person_id", 1]]
=> #<ActiveRecord::Associations::CollectionProxy [#<House id: 1, person_id: 1>]>
一切顺利,返回损坏的房子并且sql正确地加入了conditions
表。现在我想得到人的所有颜色,这被定义为房屋的所有颜色,房屋仍然只是受损的房屋。这应该返回一个空集合(因为数据库中还没有颜色)。
irb(main):007:0> person.damaged_colors
Color Load (0.4ms)
SELECT "colors".* FROM "colors"
INNER JOIN "houses" ON "colors"."house_id" = "houses"."id"
WHERE "houses"."person_id" = ? AND "conditions"."condition" = 'damaged'
[["person_id", 1]]
SQLite3::SQLException: no such column: conditions.condition:
SELECT "colors".* FROM "colors"
INNER JOIN "houses" ON "colors"."house_id" = "houses"."id"
WHERE "houses"."person_id" = ? AND "conditions"."condition" = 'damaged'
从sql字符串中可以清楚地看到连接表conditions
缺失,因此conditions.condition
不可用。如果我看到它正确,只需要查询之前的字符串:
INNER JOIN "conditions_houses" ON "conditions_houses"."house_id" = "houses"."id"
INNER JOIN "conditions" ON "conditions"."id" = "conditions_houses"."condition_id"
所以查询应该是:
SELECT "colors".* FROM "colors"
INNER JOIN "houses" ON "colors"."house_id" = "houses"."id"
INNER JOIN "conditions_houses" ON "conditions_houses"."house_id" = "houses"."id"
INNER JOIN "conditions" ON "conditions"."id" = "conditions_houses"."condition_id"
WHERE "houses"."person_id" = ? AND "conditions"."condition" = 'damaged'
这是一个rails bug还是我做错了?为什么缺少联接conditions
?
代码:
class Color < ActiveRecord::Base
belongs_to :house
end
class Condition < ActiveRecord::Base
has_and_belongs_to_many :houses
end
class House < ActiveRecord::Base
has_many :colors
belongs_to :person
has_and_belongs_to_many :conditions
scope :damaged, -> { joins(:conditions).where(:'conditions.condition' => 'damaged') }
end
class Person < ActiveRecord::Base
has_many :damaged_houses, -> { damaged }, :class_name => "House"
has_many :damaged_colors, through: :damaged_houses, :source => :colors
end
答案 0 :(得分:1)
所以我能够通过修改以下内容来让你的要点得以运行:
has_many :damaged_colors, through: :damaged_houses, :source => :colors
到
has_many :damaged_colors, -> { joins({house: :conditions}).where(:'conditions.condition' => 'damaged') }, through: :damaged_houses, :source => :colors
在评论中提到的HABTM关联似乎是一个ActiveRecord
错误...希望这有助于平均时间......
有趣的是,我把你的要点改为hm:hm并且有同样的问题......