我正在构建一个Rails应用,并且有一个名为Item的模型。它属于一个Type,并通过ItemType具有has_many Types。
通过其has_many Types关联查询项目时,我期望不会有任何结果,但是当它们属于该类型时,我会找回它们。
# models/item.rb
class Item < ApplicationRecord
has_many :item_types
has_many :types, through: :item_types
belongs_to :type, inverse_of: :items
end
# models/type.rb
class Type < ApplicationRecord
has_many :items, inverse_of: :item_type, dependent: :nullify
end
# models/itemtype.rb
class ItemType < ApplicationRecord
belongs_to :item
belongs_to :type
end
示例(预期行为):
food = Type.create
pizza = Item.create(type: food)
irb> pizza.type
food
irb> pizza.types
[]
但是,当我查询具有关联项目类型的项目并且期望没有结果时,即使没有ItemType对象,我也要取回我的项目。
irb> Item.where(type: food)
pizza
irb> Item.where(types: food)
pizza
(尽管Pizza.types返回[]的事实仍然返回了披萨)
我不确定幕后发生的事情,但是我发现这是意外的行为。为什么会发生这种情况,如何获取Item.where(types: food)
查询,但不返回结果?
答案 0 :(得分:0)
您的模型不太正确;如果您希望它们与数据库一起使用,则需要从ApplicationRecord
继承。您应该使用生成器来生成模型。
rails g model Item name:string
rails g model Type name:string
rails g model ItemType item:references type:references
然后,修改模型,使其外观如下:
class Item < ApplicationRecord
has_many :item_types
has_many :types, through: :item_types
end
class Type < ApplicationRecord
has_many :item_types
has_many :items, through: :item_types
end
class ItemType < ApplicationRecord
belongs_to :item
belongs_to :type
end
您的语法适用于伪代码,但是下面的代码应该可以正常工作
carbs = Type.create(name: 'Carbs')
pizza = Item.create(name: 'Pizza')
carbs.items << pizza
您还可以动态创建项目,如下所示:
carbs.items.create(name: 'Milkshake')
然后您可以访问以下内容:
carbs.items.first.name #=> 'Pizza'
pizza.types.map(&:name) #=> ['Carbs']
您需要查看association basics documentation的其他功能。
答案 1 :(得分:0)
我已经找到了解决此问题的可行解决方案,因此将其放在此处以供将来的读者使用。
问题在于,无论是按Item.where(type: food)
还是Item.where(types: food)
类型按类型或类型查询项目都是模棱两可的,并且似乎使用belongs_to :type
引用了Item模型中定义的belongs_to关系
要解决此问题,要按项类型查询项,您可以先使用includes(:item_types)
联接表,然后再查询其类型属于所需实例的项类型。
为我提供理想结果的查询结果是Item.includes(:item_types).where(item_type: {type: food})
。