Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kanety/ii_finder
https://github.com/kanety/ii_finder
Last synced: 2 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/kanety/ii_finder
- Owner: kanety
- License: mit
- Created: 2021-07-04T03:28:36.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2024-10-21T00:43:13.000Z (3 months ago)
- Last Synced: 2024-10-21T04:07:28.354Z (3 months ago)
- Language: Ruby
- Size: 55.7 KB
- Stars: 0
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# IIFinder
A base finder to support building relations from parameters.
## Dependencies
* ruby 2.3+
* activesupport 5.0+## Installation
Add this line to your application's Gemfile:
```ruby
gem 'ii_finder'
```Then execute:
$ bundle
## Usage
Prepare model:
```ruby
class Item < ActiveRecord::Base
end
```Prepare finder:
```ruby
class ItemsFinder < IIFinder::Base
parameters :namedef name(value)
@relation.where(name: value)
end
end
```Use finder as follows:
```ruby
ItemsFinder.call(name: 'NAME').to_sql
#=> SELECT "items".* FROM "items" WHERE "items"."name" = 'NAME'
```You can also specify relation as first argument:
```ruby
ItemsFinder.call(Item.where(id: [1, 2, 3]), name: 'NAME').to_sql
#=> SELECT "items".* FROM "items" WHERE "items"."id" IN (1, 2, 3) AND "items"."name" = 'NAME'
```### Finder
Finder loops keys of `parameters` and call the corresponding method with value of parameter as argument.
Finder method will not be called when the value of parameter is blank.
If you want to receive such value, set `allow_blank` as follows:```ruby
class ItemsFinder < IIFinder::Base
parameters :name, allow_blank: truedef name(value)
@relation.where(name: value)
end
endItemsFinder.call(name: '').to_sql
#=> SELECT "items".* FROM "items" WHERE "items"."name" = ''
```Finder has following attributes:
```ruby
class ItemsFinder < IIFinder::Base
parameters :namedef name(value)
puts "relation: #{@relation}"
puts "criteria: #{@criteria}"
puts "model: #{@model}"
puts "table: #{@table}"
end
endItemsFinder.call(name: 'NAME')
#=> relation: #'NAME'}
# model: Item
# table: #
```Return value of each finder method is merged into `@relation` if it is a kind of `ActiveRecord::Relation`.
In case you want to merge by yourself, set configuration as follows:```ruby
IIFinder.configure do |config|
config.merge_relation = false
endclass ItemsFinder < IIFinder::Base
parameters :namedef name(value)
@relation = @relation.where(name: value)
end
endItemsFinder.call(name: 'NAME').to_sql
#=> SELECT "items".* FROM "items" WHERE "items"."name" = 'NAME'
```#### Callbacks
Following callbacks are available.
* `before_call`
* `around_call`
* `after_call`For example:
```ruby
class ItemsFinder < IIFinder::Base
after_call :default_orderdef default_order
@relation = @relation.order(id: :desc)
end
endItemsFinder.call.to_sql
#=> SELECT "items".* FROM "items" ORDER BY "items"."id" DESC
```Note that finder does not handle the return value of callback.
When you want to update `@relation` in the callback,
reassign `@relation` or use methods like `where!` or `order!`.#### Coactors
You can chain multiple finders by using `coact`. For example:
```ruby
class NameFinder < IIFinder::Base
parameters :namedef name(value)
@relation.where(name: value)
end
endclass AgeFinder < IIFinder::Base
parameters :agedef age(value)
@relation.where(age: value)
end
endclass ItemsFinder < IIFinder::Base
coact NameFinder, AgeFinder
endItemsFinder.call(Item.all, name: 'name', age: 10).to_sql
#=> SELECT "items".* FROM "items" WHERE "items"."name" = 'name' AND "items"."age" = 10
```See [coactive](https://github.com/kanety/coactive) for more `coact` examples:
### Lookup for model
Finder lookups related model by its class name when the first argument of `call` is not relation.
So the name of finder class should be composed of the name of model class.
For example:```ruby
class Item < ActiveRecord::Base
endclass ItemsFinder < IIFinder::Base
endIIFinder::Base.lookup(ItemsFinder)
#=> Item
```Note that superclass of finder is also looked up until related model is found.
```ruby
class Item < ActiveRecord::Base
endclass ItemsFinder < IIFinder::Base
endclass InheritedItemsFinder < ItemsFinder
endIIFinder::Base.lookup(InheritedItemsFinder)
#=> Item
```### Scope for model
In case you want to call finder from model, include `IIFinder::Scope` into model as follows:
```ruby
class Item < ActiveRecord::Base
include IIFinder::Scope
endItem.finder_scope(name: 'NAME').to_sql
#=> SELECT "items".* FROM "items" WHERE "items"."name" = 'NAME'
```### Logging
Finder supports instrumentation hook supplied by `ActiveSupport::Notifications`.
You can enable log subscriber as follows:```ruby
IIFinder::LogSubscriber.attach_to :ii_finder
```This subscriber will write logs in debug mode as the following example:
```
Calling ItemsFinder with {:id=>1}
...
Called ItemsFinder (Duration: 9.9ms, Allocations: 915)
```## Contributing
Bug reports and pull requests are welcome at https://github.com/kanety/ii_finder.
## License
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).