3. Searching ActiveRecord...
大小比較、部分一致は得意じゃない
Issue.where("id < ?", 3).to_sql
#=> "SELECT `issues`.* FROM `issues` WHERE (id < 3)"
Issue.where("name LIKE ?", '%hoge%').to_sql
#=> "SELECT `issues`.* FROM `issues` WHERE (name LIKE '%hoge%')"
辛くなってきた…
7. What is Ransack?
ransack gem
https://github.com/activerecord-hackery/ransack
4 ActiveRecordを拡張して検索機能をつけるgem
4 設定なしで一通りの検索をカバー
4 high googleability → googleトップがgithub
4 ドキュメントが貧弱
8. How to use Ransack
In your Gemfile:
gem 'ransack'
> bundle install
Rails4, 4.1用に最適化されたbranchもある
9. Extend ActiveRecord
>bundle exec rails g model Issue name:string
>bundle exec rake db:migrate
class Issue < ActiveRecord::Base
end
で
Issue.search(name_cont: 'hoge').result.to_sql
#=> "SELECT `issues`.* FROM `issues`
# WHERE (`issues`.`name` LIKE '%hoge%')"
12. Predicates
eq, gt, gteq, lt, lteq, in, cont, start, end and more
https://github.com/activerecord-hackery/ransack/
wiki/Basic-Searching
13. Alias method
class Issue < ActiveRecord::Base
def self.search
'hoge'
end
end
Issue.search
#=> 'hoge'
Issue.ransack(name_cont: 'hoge').result.to_sql
#=> "SELECT `issues`.* FROM `issues`
# WHERE (`issues`.`name` LIKE '%hoge%')"
24. Define ransacker
4 2つのカラムの値を結合したものと比較
class Address < ActiveRecord::Base
ransacker :address do |parent|
Arel::Nodes::NamedFunction.new(
'CONCAT', [parent.table[:region],parent.table[:city]]
)
end
end
Address.search(address_cont: '大阪府大阪市')
#=> "SELECT `addresses`.* FROM `addresses`
# WHERE (CONCAT(`addresses`.`region`, '', `addresses`.`city`)
# LIKE '%大阪府大阪市%')"
25. Define ransacker
4 半角スペースを無視した検索
ransacker :name_without_spaces, formatter: proc { |v| v.gsub(' ', '') } do |parent|
Arel::Nodes::NamedFunction.new(
'REPLACE', [parent.table[:name], ' ', '']
)
end
Issue.search(name_without_spaces_eq: 'h o g e').result.to_sql
#=> "SELECT `issues`.* FROM `issues`
# WHERE REPLACE(`issues`.`name`, ' ', '') = 'hoge'"