class Scopable
Constants
- VERSION
Attributes
model[R]
scopes[R]
Public Class Methods
model(model = nil)
click to toggle source
# File lib/scopable.rb, line 87 def self.model(model = nil) @model ||= model end
new(model = nil, scopes = nil)
click to toggle source
# File lib/scopable.rb, line 7 def initialize(model = nil, scopes = nil) @model = model || self.class.model @scopes = scopes || self.class.scopes end
resolve(params = {})
click to toggle source
# File lib/scopable.rb, line 83 def self.resolve(params = {}) new.resolve(params) end
scope(name, options = {}, &block)
click to toggle source
# File lib/scopable.rb, line 95 def self.scope(name, options = {}, &block) scopes.store name, options.merge(block: block) end
scopes()
click to toggle source
# File lib/scopable.rb, line 91 def self.scopes @scopes ||= {} end
Public Instance Methods
delegator(relation, value, params)
click to toggle source
# File lib/scopable.rb, line 12 def delegator(relation, value, params) SimpleDelegator.new(relation).tap do |delegator| delegator.define_singleton_method(:value) do value end delegator.define_singleton_method(:params) do params end end end
resolve(params = {})
click to toggle source
# File lib/scopable.rb, line 23 def resolve(params = {}) params = params.with_indifferent_access scopes.reduce(model.all) do |relation, scope| name, options = *scope # Resolve param name. param = options[:param] || name # Resolve a value for the scope. value = options[:value] || params[param] || options[:default] # When value is empty treat it as nil. value = nil if value.respond_to?(:empty?) && value.empty? # When a nil value was given either skip the scope or bail with #none (if the required options was used). if value.nil? if options[:required] break relation.none else next relation end end # Cast boolean-like strings. case value.to_s when /\A(false|no|off)\z/ value = false when /\A(true|yes|on)\z/ value = true end # Enforce 'if' option. if options[:if] unless delegator(relation, value, params).instance_exec(&options[:if]) next relation end end # Enforce 'unless' option. if options[:unless] if delegator(relation, value, params).instance_exec(&options[:unless]) next relation end end # Bail if the value is false or nil. next relation unless value # When a block is present, use that, otherwise call the scope method. if options[:block].present? delegator(relation, value, params).instance_exec(&options[:block]) elsif value == true relation.send(name) else relation.send(name, value) end end end