HasFinderというRails pluginが激しく便利
nick – HasFinder — It’s Now Easier than ever to create complex, re-usable SQL queries
一言で説明すると「いろいろな条件のFindをモデルのメソッドにして便利に利用できる」というもの。
導入
とりあえずは入れて使う方法から。
$ sudo gem install has_finder
environment.rbに以下追記。
gem 'has_finder'
require 'has_finder'
使ってみる
早速メソッド作ってみる。
class Item < ActiveRecord::Base
has_finder :stocked, :conditions => ["stock > 0"]
has_finder :has_image, :conditions => {:has_image => true}
end
これだけなら別に普通にメソッド定義できるものをちょっと簡単に書けるようにしただけのことでフーンってかんじ。
だがこれらのメソッドをいろいろと組み合わせて柔軟に使っていけるところがHasFinderの真骨頂。
手始めとしてメソッドを連結して使ったりとか。
items = Item.stocked.has_image
絞り込み条件がいいかんじにDRYに。
この後にさらにfindで絞り込んだり並べ替えたりも可能。集計関数も行ける。
items = Item.stocked.has_image.find(:all, :conditions => ["maker_id = ?", params[:maker_id]], :order => 'price')
items = Item.stocked.has_image.count
関連といっしょに使っても問題なし。
class Category < ActiveRecord::Base
has_many :items
end
class Item < ActiveRecord::Base
has_one :category
has_finder :stocked, :conditions => ["stock > 0"]
has_finder :has_image, :conditions => {has_image => true}
end
category.items.stocked
ページネーションもおk。
items = Item.stocked.paginate(:page => params[:page], :conditions => ["category_id = ?", @category.id], :order => 'name', :per_page => 20)
メソッドに引数を取って条件の値の指定を動的に行うこともできる。
class Item < ActiveRecord::Base
has_finder :price_under, lambda {|price| { :conditions => ["price < = ?" , price] } }
end
items = Item.price_under(10000)
ほかAssociation extentionsみたいなこともできる。
もうすぐ標準
RailsのEdgeでは本体に取り込まれている模様。
Ryan’s Scraps: What’s New in Edge Rails: Has Finder Functionality
has_finderではなくnamed_scopeで定義するようになってたり若干変わってるようだけど、もうすぐ標準で使えるようになるみたいですな。