Rails 4: 查找所有 has_many 中没有 parents 的条目 :though self-referential join
Rails 4: Find all entries with no parents in has_many :though self-referential join
所以我的设置是我有类别,一个 category
可以有很多 parents 和很多 children 通过 self-referential 加入 table category_relationships
。使用下面的内容,这一切在创建和检索这些关系时都非常有效。
不过我现在想做的是,找到没有任何 parents 的类别(基本上是所有 top-level 类别)。
我已经尝试了几种不同的 where.not
类型实现,但就是想不出正确的表达式。
category.rb
# == Schema Information
#
# Table name: categories
#
# created_at :datetime not null
# id :integer not null, primary key
# name :string(255) not null
# updated_at :datetime not null
#
class Category < ActiveRecord::Base
# CategoryRelationships (Parents & Children)
# ==========================================================================================================
has_many :parent_child_relationships,
class_name: "CategoryRelationship",
foreign_key: :child_id,
inverse_of: :parent,
dependent: :destroy
has_many :parents,
through: :parent_child_relationships,
source: :parent
has_many :child_parent_relationships,
class_name: "CategoryRelationship",
foreign_key: :parent_id,
inverse_of: :child,
dependent: :destroy
has_many :children,
through: :child_parent_relationships,
source: :child
end
category_relationships.rb
# == Schema Information
#
# Table name: category_relationships
#
# child_id :integer not null
# created_at :datetime not null
# id :integer not null, primary key
# parent_id :integer not null
# updated_at :datetime not null
#
class CategoryRelationship < ActiveRecord::Base
# Parent (Category)
# ==========================================================================================================
belongs_to :parent,
class_name: "Category",
inverse_of: :parent_child_relationships
# Child (Category)
# ==========================================================================================================
belongs_to :child,
class_name: "Category",
inverse_of: :child_parent_relationships
# Validations
# ==========================================================================================================
validates :parent,
presence: true
validates :child,
presence: true
end
我最终选择了:
Category.joins("LEFT OUTER JOIN category_relationships ON categories.id = category_relationships.child_id").where("category_relationships.child_id IS NULL")
不过,我不确定它的效率如何,也不确定是否有更好的方法,因为我听说 LEFT OUTER JOIN
在较大的数据集上可能成本很高。
所以我的设置是我有类别,一个 category
可以有很多 parents 和很多 children 通过 self-referential 加入 table category_relationships
。使用下面的内容,这一切在创建和检索这些关系时都非常有效。
不过我现在想做的是,找到没有任何 parents 的类别(基本上是所有 top-level 类别)。
我已经尝试了几种不同的 where.not
类型实现,但就是想不出正确的表达式。
category.rb
# == Schema Information
#
# Table name: categories
#
# created_at :datetime not null
# id :integer not null, primary key
# name :string(255) not null
# updated_at :datetime not null
#
class Category < ActiveRecord::Base
# CategoryRelationships (Parents & Children)
# ==========================================================================================================
has_many :parent_child_relationships,
class_name: "CategoryRelationship",
foreign_key: :child_id,
inverse_of: :parent,
dependent: :destroy
has_many :parents,
through: :parent_child_relationships,
source: :parent
has_many :child_parent_relationships,
class_name: "CategoryRelationship",
foreign_key: :parent_id,
inverse_of: :child,
dependent: :destroy
has_many :children,
through: :child_parent_relationships,
source: :child
end
category_relationships.rb
# == Schema Information
#
# Table name: category_relationships
#
# child_id :integer not null
# created_at :datetime not null
# id :integer not null, primary key
# parent_id :integer not null
# updated_at :datetime not null
#
class CategoryRelationship < ActiveRecord::Base
# Parent (Category)
# ==========================================================================================================
belongs_to :parent,
class_name: "Category",
inverse_of: :parent_child_relationships
# Child (Category)
# ==========================================================================================================
belongs_to :child,
class_name: "Category",
inverse_of: :child_parent_relationships
# Validations
# ==========================================================================================================
validates :parent,
presence: true
validates :child,
presence: true
end
我最终选择了:
Category.joins("LEFT OUTER JOIN category_relationships ON categories.id = category_relationships.child_id").where("category_relationships.child_id IS NULL")
不过,我不确定它的效率如何,也不确定是否有更好的方法,因为我听说 LEFT OUTER JOIN
在较大的数据集上可能成本很高。