Dynamic Default Scoping

What is the library for?

Well, at the moment ActiveRecord (3.0.3) does not allow to pass procs and lambdas to default_scope. That’s strange, isn’t it? Because scope successfully handles arguments of those types, so why default_scope does not?

How to use?

Here is an example:

class Post < ActiveRecord::Base
  include DynamicDefaultScoping

  default_scope :language, lambda { |*args|
    case locale = (args[0].presence || I18n.locale).to_s
    when 'any', 'all'
      where :locale => I18n.available_locales.map(&:to_s)
    else
      where :locale => locale
    end
  }
end

You can overwrite the default value for the locale attribute calling the scope by name and passing another value.

What are the constrains?

Because of the internal implementation of ActiveRecord and friends, the library *should be included only after* all calls to the regular default_scope and scope, especially when they use new aRel syntax like where, order, limit, etc.

Here is how it should be:

class Article < ActiveRecord::Base
  default_scope order(:created_at).reverse_order

  scope :published, where(:published => true)

  include DynamicDefaultScoping

  default_scope :recent, lambda {
    where [ 'created_at > ?', Time.now - 5.days ]
  }
end

When there will be a normal implementation of this feature?

rails.lighthouseapp.com/projects/8994/tickets/1812-default_scope-cant-take-procs

Credits