zolter
zolter

Reputation: 7160

How should I use scope in Rails 3?

I have two models:

First:

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

Second:

class Country < ActiveRecord::Base
  belongs_to :country_list
end

I need create a scope in CountryList model, which will include all records without association with country.

Smth like this:

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

Upvotes: 0

Views: 381

Answers (3)

BitOfUniverse
BitOfUniverse

Reputation: 6011

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

CountryList.countryless.all

Upvotes: 1

Kristian PD
Kristian PD

Reputation: 2695

I don't have a terminal here but:

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

I'm pretty sure the #{id} part will give you a warning, but I can't remember the proper syntax in R3.

Upvotes: 1

Marian Theisen
Marian Theisen

Reputation: 6354

you can do sth like this:

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

but plz note, this may not be the fastest query in the west. a better approach would be to use a ActiveRecord counter_cache, but this needs an additional column, and is a kind of denormalization, you can find details here. counter_cache is definitely a loot faster, and if you don't step out of ActiveRecord, i.e. you don't manipulate your database with raw SQL thus bypassing your ActiveRecord ORM, the denormalization won't hurt you.

btw. im assuming you meant

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

Upvotes: 1

Related Questions