THINKING MEGANE

静的データを扱う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と組み合わせて更に便利に使ってみてはどうでしょうか。

このエントリーをはてなブックマークに追加