Class: EasyFilters::Filter

Inherits:
Object
  • Object
show all
Defined in:
lib/easy_filters/filter.rb

Overview

Base class for any object used for keeping filtering logic + criteria together.

This class provides the following functionality out-of-the-box:

- Automatic values sanitizing: The values passed to the #initialize method
  will be fed into #sanitize and the result of that process will be used for
  setting the filter values.
- Hash-like accessors: Any value for the filters can be get/set via []/[]=,
  just like Hashes.

For examples, please:

See Also:

  • ArticlesFilter
  • SupplementFilter

Direct Known Subclasses

ModelFilter

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Filter

Initialize a new filter with the given options.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/easy_filters/filter.rb', line 56

def initialize(options = {})
  @options = { values: nil, store: nil, persist: false }.merge options

  # This is the order of precedence:
  # values => store => defaults
  actual = options[:values]
  store  = options[:store]
  
  source = self.class.defaults
  
  source = store[self.class.global_key][key] if store && store[self.class.global_key] && store[self.class.global_key][key]
  source = actual if actual

  self.values = sanitize source

  self
end

Class Method Details

.defaultsObject

Default values. This method should be overridden when in need to specify particular defaults for a subclass.



20
21
22
# File 'lib/easy_filters/filter.rb', line 20

def self.defaults
  {}
end

.global_keyObject

Global key that will contain the values for any filter class inside the store or the request values source. In extension, the store options should be structured like this:

{
  :"#{Filter.global_key}" => {
    :"#{@filter.key}" => {
      :value => 'for a filter field'
    }
  }
}


35
36
37
# File 'lib/easy_filters/filter.rb', line 35

def self.global_key
  :filter
end

.keyObject

Particular key that will contain the values for this specific filter class in the store/request values source - under the Filter#global_key main key. In extension, the store options should be structured like this:

{
  :"#{Filter.global_key}" => {
    :"#{@filter.key}" => {
      :value => 'for a filter field'
    }
  }
}


51
52
53
# File 'lib/easy_filters/filter.rb', line 51

def self.key
  self.name.to_sym
end

Instance Method Details

#[](key) ⇒ Object

Filter field value accessor. Provides a Hash-like API for getting the values set to the different fields of this filter. Will return the value set for :key or nil.



96
97
98
# File 'lib/easy_filters/filter.rb', line 96

def [] key
  values[key] if values.has_key? key
end

#[]=(key, value) ⇒ Object

Filter field value writer. Provides a Hash-like API for setting the values of the filter fields.



102
103
104
# File 'lib/easy_filters/filter.rb', line 102

def []=(key, value)
  values[key] = value
end

#allObject

Get all the matching records to the current filter criteria. This method must be implemented in subclasses.



144
145
146
# File 'lib/easy_filters/filter.rb', line 144

def all
  throw NotImplementedError
end

#any?Boolean

Answer whether any filter values have been applied. Will return true if the current values differ from the default ones.

Returns:

  • (Boolean)


108
109
110
# File 'lib/easy_filters/filter.rb', line 108

def any?
  self.class.defaults != self.values
end

#clear!Object

Clear the values of the filters - set them to the defaults.



138
139
140
# File 'lib/easy_filters/filter.rb', line 138

def clear!
  self.values = self.class.defaults
end

#keyObject

Instance method used for convenience. Just a wrapper for the class method #key.



89
90
91
# File 'lib/easy_filters/filter.rb', line 89

def key
  self.class.key
end

#persist!(store) ⇒ Object

Persist the current values to the given :store.



132
133
134
135
# File 'lib/easy_filters/filter.rb', line 132

def persist!(store)
  store[self.class.global_key] ||= {}
  store[self.class.global_key][self.class.key] = self.values
end

#sanitize(values) ⇒ Object

Conditionally clean up some values after the initialization is finished Note:

These method have sense when the subclasses uses it, 
Filter class will not allows to pass any value 
due that the defaults is an empty hash so the valid keys is an empty array


79
80
81
82
83
84
85
# File 'lib/easy_filters/filter.rb', line 79

def sanitize(values)
  valid_keys = self.class.defaults.keys
  values.inject(self.class.defaults) do |carry, (k, v)|
    carry[k] = v if valid_keys.include?(k) && !v.blank?
    carry
  end
end

#valuesObject

Gets the values for this filter.



113
114
115
# File 'lib/easy_filters/filter.rb', line 113

def values
  @values
end

#values=(new_values) ⇒ Object

Sets the values for this filter to :new_values. Will persist if the :persist option was set to true when creating this object and a valid store has been provided.



120
121
122
123
124
125
126
127
128
129
# File 'lib/easy_filters/filter.rb', line 120

def values=(new_values)
  @values = new_values

  # Define getters for each of the new_values
  new_values.each do |key, value|
    self.class.send(:define_method, key, proc { self[key] }) unless self.respond_to? key
  end

  self.persist! @options[:store] if @options[:store] && @options[:persist]
end