Class: Lupa::Search
- Inherits:
-
Object
- Object
- Lupa::Search
- Defined in:
- lib/lupa/search.rb
Overview
Base class for creating search filters using object-oriented design patterns.
Lupa::Search provides a structured way to build complex search functionality by defining search methods in a nested Scope class. Each search attribute maps to a method in the Scope class, allowing for clean, testable, and maintainable search logic.
Basic Structure
To create a search class:
-
Inherit from ‘Lupa::Search`
-
Define a nested ‘Scope` class
-
Implement search methods in the Scope class
-
Optionally define ‘default_search_attributes`
Features
-
Framework and ORM agnostic
-
Works with any object that supports method chaining (ActiveRecord, Array, etc.)
-
Automatic attribute symbolization and blank value filtering
-
Support for nested hash attributes
-
Default search attributes and default scope
-
Search class composition for reusability
-
Method delegation to search results
Defined Under Namespace
Classes: Scope
Instance Attribute Summary collapse
-
#scope ⇒ Object
readonly
Returns the original scope object passed to the search class.
-
#search_attributes ⇒ Hash
readonly
Returns all search attributes including default search attributes.
Class Method Summary collapse
-
.search(attributes) ⇒ Lupa::Search
Class method to create a new search instance and perform a search in one call.
Instance Method Summary collapse
-
#default_search_attributes ⇒ Hash
Returns default search attributes that should always be applied.
-
#initialize(scope) ⇒ Lupa::Search
constructor
Creates a new search instance with the given scope.
-
#method_missing(method_sym, *arguments, &block) ⇒ Object
Delegates method calls to the search results.
-
#results ⇒ Object
Returns the search results after applying all search methods.
-
#search(attributes) ⇒ self
Performs the search with the given attributes.
Constructor Details
#initialize(scope) ⇒ Lupa::Search
Creates a new search instance with the given scope.
The scope can be any object that supports method chaining, such as an ActiveRecord::Relation, Mongoid::Criteria, or even a plain Ruby Array.
276 277 278 |
# File 'lib/lupa/search.rb', line 276 def initialize(scope) @scope = scope end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_sym, *arguments, &block) ⇒ Object
This is what allows search objects to be used directly in views without explicitly calling ‘.results` first
Delegates method calls to the search results.
This allows you to call any method that the results object responds to directly on the search instance, making the search object behave like the results collection.
630 631 632 633 634 635 636 |
# File 'lib/lupa/search.rb', line 630 def method_missing(method_sym, *arguments, &block) if results.respond_to?(method_sym) results.send(method_sym, *arguments, &block) else raise Lupa::ResultMethodNotImplementedError, "The resulting scope does not respond to #{method_sym} method." end end |
Instance Attribute Details
#scope ⇒ Object (readonly)
This returns the original scope, not the filtered results. Use ‘results` to get the filtered scope after search methods are applied.
Returns the original scope object passed to the search class. This is the base scope that all search methods will operate on.
181 182 183 |
# File 'lib/lupa/search.rb', line 181 def scope @scope end |
#search_attributes ⇒ Hash (readonly)
Returns all search attributes including default search attributes. All keys are automatically symbolized and blank values are removed.
230 231 232 |
# File 'lib/lupa/search.rb', line 230 def search_attributes @search_attributes end |
Class Method Details
.search(attributes) ⇒ Lupa::Search
If you need to pass a custom scope, use ‘ProductSearch.new(scope).search(attributes)` instead
Class method to create a new search instance and perform a search in one call.
This is a convenience method that creates a new instance without a scope parameter and then calls the instance ‘search` method. This only works if you’ve defined a default scope in your ‘initialize` method.
499 500 501 502 503 |
# File 'lib/lupa/search.rb', line 499 def self.search(attributes) new.search(attributes) rescue ArgumentError raise Lupa::DefaultScopeError, "You need to define a default scope in order to user search class method." end |
Instance Method Details
#default_search_attributes ⇒ Hash
This method must return a Hash or a Lupa::DefaultSearchAttributesError will be raised
Returns default search attributes that should always be applied.
Override this method in your search class to define attributes that should always be included in the search, regardless of what’s passed to the ‘search` method. Default attributes can be overridden by explicitly passing them in search params.
352 353 354 |
# File 'lib/lupa/search.rb', line 352 def default_search_attributes {} end |
#results ⇒ Object
Methods in your Scope class should return either the modified scope or nil (if no filtering should be applied). Returning nil prevents the scope from being updated for that particular search method.
Returns the search results after applying all search methods.
This method executes the search by calling each method defined in the Scope class that corresponds to a key in search_attributes. The methods are called in the order they appear in the search_attributes hash. Results are memoized, so calling this method multiple times won’t re-execute the search.
570 571 572 |
# File 'lib/lupa/search.rb', line 570 def results @results ||= run end |
#search(attributes) ⇒ self
Search methods are not executed until you call ‘results` or a delegated method
Performs the search with the given attributes.
This method processes the search attributes (symbolizing keys, merging with defaults, removing blank values), validates that all attribute keys have corresponding methods in the Scope class, and returns self for method chaining.
430 431 432 433 434 435 436 437 |
# File 'lib/lupa/search.rb', line 430 def search(attributes) raise Lupa::SearchAttributesError, "Your search params needs to be a hash." unless attributes.respond_to?(:keys) set_search_attributes(attributes) set_scope_class check_method_definitions self end |