静的データを扱うActiveHashでページングとライク検索するgem達をつくった
静的データをActiveRecord的に扱えて便利なActiveHashですが、ページングとライク検索が必要になったのでgemをつくりました。
ページングを行えるようにする active_hash-kaminari
と、
ライク検索を行えるようにする active_hash-like
です。
active_hash-kaminari
ページングを行いたいActiveHashのクラスにPaginatable
モジュールをprepend
します。
class Country < ActiveHash::Base
prepend ActiveHash::Paginatable
...
end
ページングにはKaminariを使っています。モジュールをprependすることにより、検索結果が Kaminari::PaginatableArray
でラップされるようになり、ページングが可能になります。
Country.all.page(1).per(10)
もちろんViewでも使えます。
<%= paginate @counties %>
active_hash-like
gemをインストールすると、ActiveHashでlike
が使えるようになります。
class Country < ActiveHash::Base; end
Country.like(name: 'Cana%')
複数条件のうち、ひとつをlikeで検索する場合はwhere内ActiveHash::Match::Like
マッチャーを使います。
Country.where(name: ActiveHash::Match::Like.new('Cana%'))
Custom Matcher
ActiveHash::Match::Like
はカスタムマッチャーのひとつで、マッチャーは独自でつくることが可能です。
マッチャーはcall
メソッドを持つ必要があります。
class MyCustomMatcher
attr_accessor :pattern
def initialize(pattern)
self.pattern = pattern
end
def call(value)
# Case ignore matcher
value.upcase == pattern.upcase
end
end
Country.where(name: MyCustomMatcher.new('pattern'))
call
メソッドを持つProc
オブジェクトも使うことができます。
Country.where(name: ->(value){value == 'some value'})
OR 条件
あいまい検索という括りでOR
検索も行うことができるようになります。
Country.where(name: 'Canada', or: {field1: 'foo', field2: 'bar'})
#=> name = 'Canada' and (field1 = 'foo' or field2 = 'bar')
OR条件の対象のカラムが同じ場合(IN相当)はまだ未実装なのでカスタムマッチャーを使ってください。
Country.where(name: ->(val){val == 'Canada' || val == 'US'})
まとめ
ActiveHash、静的データを扱うのにとても便利なので、active_hash-kaminariとactive_hash-likeと組み合わせて更に便利に使ってみてはどうでしょうか。