Default Scopes and Inheritance to the rescue
Published over 5 years ago

On my one of the current projects, there are two primary models each with a flag called approved_. 99% of the front end part deals with only approved items. Unapproved items are usually only in the admin panel side of the story. So I started with using a namedscope called approved:

class Item < ActiveRecord::Base
  has_many :tags

  default_scope :order => 'items.name ASC'
  named_scope :approved, :conditions => { :published => true }
end

And now I’d have to use Item.approved. everywhere in my application. But that became a bit too cumbersome sooner than later. Playing around with this a bit, I came up with the solution using default_scope and the good ol’ inheritance:

class Item < ActiveRecord::Base
  has_many :tags

  default_scope :order => 'items.name ASC'
end

class PublishedItem < Item
  set_table_name 'items'
  set_inheritance_column nil # hax?

  default_scope :conditions => { :published => true }, :order => 'items.name ASC'
end

Checking this on console :

>> p = PublishedItem.first
  SELECT * FROM `items` WHERE (`items`.`published` = 1) ORDER BY items.name ASC LIMIT 1

>> i = Item.first
  SELECT * FROM `items` ORDER BY items.name ASC LIMIT 1

Seems to work just fine.

You could do it the other way around too:

class RawItem < ActiveRecord::Base
  set_table_name 'items'
  has_many :tags

  default_scope :order => 'items.name ASC'
end

class Item < RawItem
  set_table_name 'items'
  set_inheritance_column nil # hax?

  default_scope :conditions => { :published => true }, :order => 'items.name ASC'
end

Whichever one works for you.

Please note that the above code is NOT using STI_. It’s using set_inheritancecolumn nil workaround to bypass the Active Record STI stuff and rely just on the ruby inheritance.