Giter VIP home page Giter VIP logo

has_scope's Introduction

HasScope

Gem Version Build Status Code Climate

Has scope allows you to map incoming controller parameters to named scopes in your resources. Imagine the following model called graduations:

class Graduation < ActiveRecord::Base
  scope :featured, -> { where(:featured => true) }
  scope :by_degree, -> degree { where(:degree => degree) }
  scope :by_period, -> started_at, ended_at { where("started_at = ? AND ended_at = ?", started_at, ended_at) }
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
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], :type => :hash

  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?by_period[started_at]=20100701&by_period[ended_at]=20101013
#=> brings graduations in the given period

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

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

Add has_scope to your Gemfile or install it from Rubygems.

gem 'has_scope'

Options

HasScope supports several options:

  • :type - Checks the type of the parameter sent. By default, it does not allow hashes or arrays to be given, except if type :hash or :array are set. Symbols are never permitted to prevent memory leaks, so ensure any routing constraints you have that add parameters use string values.

  • :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. Whenever supplied the scope is always called.

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

  • :in - A shortcut for combining the :using option with nested hashes.

Boolean usage

If type: :boolean is set it just calls the named scope, without any arguments, when parameter is set to a "true" value. 'true' and '1' are parsed as true, everything else as false.

When boolean scope is set up with allow_blank: true, it will call the scope with the value as usual scope.

has_scope :visible, type: :boolean
has_scope :active, type: :boolean, allow_blank: true

# and models with
scope :visible, -> { where(visible: true) }
scope :active, ->(value = true) { where(active: value) }

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 without :allow_blank, 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

Keyword arguments

Scopes with keyword arguments need to be called in a block:

# in the model
scope :for_course, lambda { |course_id:| where(course_id: course_id) }

# in the controller
has_scope :for_course do |controller, scope, value|
  scope.for_course(course_id: value)
end

Apply scope on every request

To apply scope on every request set default value and allow_blank: true:

has_scope :available, default: nil, allow_blank: true, only: :show, unless: :admin?

# model:
scope :available, ->(*) { where(blocked: false) }

This will allow usual users to get only available items, but admins will be able to access blocked items too.

Bugs and Feedback

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

http://github.com/plataformatec/has_scope/issues

MIT License. Copyright 2009-2016 Plataformatec. http://blog.plataformatec.com.br

has_scope's People

Contributors

josevalim avatar carlosantoniodasilva avatar lucasmazza avatar spectator avatar kreeger avatar rafaelfranca avatar jackdempsey avatar tmaier avatar nickelser avatar printercu avatar sobrinho avatar iain avatar fabianoarruda avatar beerlington avatar nashby avatar tfwright avatar salimane avatar splattael avatar nruth avatar hugobarauna avatar georgeguimaraes avatar fabiokr avatar dim avatar dhyegocalota avatar atul9 avatar

Stargazers

Dunya Kirkali avatar

Watchers

Erik Berlin avatar James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.