如何将此查询转换为ActiveRecord逻辑?

时间:2015-03-30 10:16:40

标签: sql ruby-on-rails activerecord

我在铁轨上工作。我的模型是这样的:

class Topic < ActiveRecord::Base
  has_many :topics, dependent: :delete_all
  belongs_to :parent, foreign_key: 'topic_id', class_name: 'Topic'
  has_many :contents

  validates :name, uniqueness: true, presence: true
end

所以我有一个主题,可以有很多&#34;子主题&#34;。 每个子主题都可以包含许多子主题,无限期。我试图制作一种方法让我回归所有&#34; leaf&#34;话题。叶主题是没有子主题的主题。

def self.leafs
  where(???)
end

我无法在主动记录逻辑中表达这一点,所以实际上我使用了这个查询:

Topic.find_by_sql("SELECT * FROM topics WHERE id NOT IN (SELECT t.topic_id FROM topics t WHERE topic_id IS NOT NULL)")

如何以活动记录方式写这个?

3 个答案:

答案 0 :(得分:1)

def self.leafs
  topics.where("topic_id IS NOT NULL")
end

ActiveRecord 4.0及更高版本添加了where.not所以你可以这样做:

scope :leafs, -> topics.where.not(topic_id: nil)


scope :without_topics, includes(:topics).where(:topics => { :id => nil })

答案 1 :(得分:1)

试试这个:

child_ids_with_topic_id = where.not(topic_id: nil).pluck(:topic_id)
where.not(id: child_ids_with_topic_id)

答案 2 :(得分:0)

虽然我不确定,但我已尝试使用此Rails 3 finding parents which have no child

scope :leafs, joins("left join topics as sub_topics sub_topics.topic_id = topics.id").where("topics.topic_id is null")