has_many 通过=> 查找不匹配的记录

has_many through => find not matching records

我希望能够找到无人居住的蜂箱,但没有找到任何解决方案。 你能帮我吗 ? 目标是能够做到 Hive.unpopulated 主要问题是 most_recent,但我可以使用原始 SQL,但我找不到正确的查询。

这是我的 类 :

class Hive < ApplicationRecord
  has_many :moves, dependent: :destroy
  has_many :yards, through: :moves
  has_many :populations, -> { where(:most_recent => true) }
  has_many :colonies, through: :populations 
  
  validates :name, uniqueness: true
  
  def hive_with_colony 
    "#{name} (colony #{if self.colonies.count > 0 then self.colonies.last.id end})"
  end
  
  def self.populated
    Hive.joins(:populations)
  end
  def self.unpopulated
    
  end
  
end
class Population < ApplicationRecord
  belongs_to :hive
  belongs_to :colony
  
  after_create :mark_most_recent
  before_create :mark_end
class Colony < ApplicationRecord
  has_many :populations, -> { where(:most_recent => true) }
  has_many :hives, through: :populations
  has_many :visits
  has_many :varroas
  
  has_many :most_recents_populations, -> { where(:most_recent => true) }, :class_name => 'Population'
  scope :last_population_completed, -> { joins(:populations).where('populations.most_recent=?', true)}

我想你可以对 select 不在填充列表中的蜂巢做一个简单的查询,所以:

def self.unpopulated
  where.not(id: populated.select(:id))
end

另一种选择是 LEFT OUTER JOIN 并选择右侧没有设置 population id 的行。

def self.unpopulated
  left_outer_joins(:populations).where(populations: { id: nil })
end

这取决于你的数据,Thanh 的版本(它比较了一个潜在的巨大 id 列表)或这个版本(它使一个明显更复杂的连接但不需要与一个 id 列表进行比较)性能更高.