我应该如何在Rails 3中使用范围?

时间:2011-09-20 09:57:27

标签: ruby-on-rails scope associations relational-database

我有两种模式:

首先:

class CountryList < ActiveRecord::Base
  has_one :country, :dependent => :nullify
end

第二

class Country < ActiveRecord::Base
  belongs_to :country_list
end

我需要在CountryList模型中创建一个范围,该范围将包括所有与国家/地区无关的记录。

像这样的Smth:

CountryList.all.each do |country_list|
  country_list.country.nil?
end 

3 个答案:

答案 0 :(得分:1)

你可以这样做:

class CountryList < ActiveRecord::Base
  def self.without_countries
    joins(:country).
    select("country_lists.*, COUNT(countries.id) AS country_count").
    group("country_lists.id").
    having("country_count = 0")
  end
end

但请注意,这可能不是西方最快的查询。 更好的方法是使用ActiveRecord counter_cache,但这需要一个额外的列,并且是一种非规范化,您可以找到详细信息herecounter_cache绝对是一个更快的战利品,如果你不退出ActiveRecord,即你没有使用原始SQL操纵你的数据库,从而绕过你的ActiveRecord ORM,反规范化不会伤害你。

顺便说一句。我假设你的意思

CountryList.all.select do |country_list|
  country_list.countries.empty?
end

答案 1 :(得分:1)

我这里没有终端,但是:

class CountryList < ActiveRecord::Base
   scope :no_country, joins('LEFT OUTER JOIN countries ON (country_list_id = #{id})').where(:countries => {:country_id => nil})
end

我很确定#{id}部分会给你一个警告,但我不记得R3中的正确语法。

答案 2 :(得分:1)

class CountryList < ActiveRecord::Base
  has_one :country, :dependent => :nullify
  scope :countryless, where(:country_id => nil)
end

CountryList.countryless.all