Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
*Patched version that adds some options for has_scope and apply_scopes* Maps controller filters to your resource scopes
branch: master

This branch is 6 commits ahead, 85 commits behind plataformatec:master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
lib
test
MIT-LICENSE
README.rdoc
Rakefile
has_scope.gemspec
init.rb

README.rdoc

HasScope

Has scope allows you to easily create controller filters based on your resources named scopes. Imagine the following model called graduations:

class Graduation < ActiveRecord::Base
  named_scope :featured, :conditions => { :featured => true }
  named_scope :by_degree, proc {|degree| { :conditions => { :degree => degree } } }
end

You can use those named scopes as filters by declaring them on your controller:

class GraduationsController < ApplicationController
  has_scope :featured, :type => :boolean
  has_scope :by_degree, :default => 'foo', :always => true
end

Now, if you want to apply them to an specific resource, you just need to call apply_scopes:

class GraduationsController < ApplicationController
  has_scope :featured, :type => :boolean
  has_scope :by_degree
  has_scope :by_period, :using => [:started_at, :ended_at]

  def index
    @graduations = apply_scopes(Graduation).all
  end
end

Then for each request:

/graduations
#=> acts like a normal request

/graduations?featured=true
#=> calls the named scope and bring featured graduations

/graduations?featured=true&by_degree=phd
#=> brings featured graduations with phd degree

/graduations?params[by_period][started_at]=20100701&params[by_period][ended_at]=20101013
#=> brings graduations in the given period

You can retrieve all the scopes applied in one action with current_scopes method. In the last case, it would return: { :featured => true, :by_degree => “phd” }.

Installation

Rails 3

gem 'has_scope', :git => 'git://github.com/rymai/has_scope.git'

has_scope options

has_scope supports several options:

  • :type - Checks the type of the parameter sent. If set to :boolean it just calls the named scope, without any argument. By default, it does not allow hashes or arrays to be given, except if type :hash or :array are set.

  • :only - In which actions the scope is applied.

  • :except - In which actions the scope is not applied.

  • :as - The key in the params hash expected to find the scope. Defaults to the scope name.

  • :using - The subkeys to be used as args when type is a hash.

  • :if - Specifies a method, proc or string to call to determine if the scope should apply.

  • :unless - Specifies a method, proc or string to call to determine if the scope should NOT apply.

  • :default - Default value for the scope. Default scope is called only if no other scope is given, to always call the default scope, see the :always option.

  • :always - Whenever supplied, the scope is always called (with the default or the given value).

  • :allow_blank - Blank values are not sent to scopes by default. Set to true to overwrite.

apply_scopes options

apply_scopes supports several options:

  • :hash - Override the default request's params hash.

  • :default - Override any scopes with the :default option and called when no scope is present in the given :hash (or request's params hash by default).

Just call apply_scopes like this:

def index
  @flowers = apply_scopes(Flower, :default => { :color => 'red', :size => 'huge' }).all
end

Then for each request:

/flowers
#=> no explicit scope given, calls the color('red') and size('huge') default scopes

/flowers?size=tiny
#=> explicit scope given, calls given size('tiny') scope and color('red') default scope

/flowers?color=blue
#=> calls color('blue') (as a normal explicit given scope) scope and size('huge') default scope

Block usage

has_scope also accepts a block. The controller, current scope and value are yielded to the block so the user can apply the scope on its own. This is useful in case we need to manipulate the given value:

has_scope :category do |controller, scope, value|
  value != "all" ? scope.by_category(value) : scope
end

When used with booleans, it just receives two arguments and is just invoked if true is given:

has_scope :not_voted_by_me, :type => :boolean do |controller, scope|
  scope.not_voted_by(controller.current_user.id) 
end

Contributions

Rémy Coutable - github.com/rymai

  • Added apply_scopes's :default option.

  • Added apply_scopes's :hash option.

  • Changed has_scope's :default option behavior, to has a real “default” behavior (called only when no scopes is present in the params) and not an “always” behavior (called when no value for this scope is present in the params).

  • Added has_scope's :always option (you must set the :default option for this option to be applied) allowing the same behavior as the former has_scope's :default option.

Bugs and Feedback

If you discover any bugs or want to drop a line, feel free to create an issue on GitHub.

github.com/plataformatec/has_scope/issues

MIT License. Copyright 2009 Plataforma Tecnologia. blog.plataformatec.com.br

Something went wrong with that request. Please try again.