Successfully reported this slideshow.
Your SlideShare is downloading. ×

ransack, ransack, ransack

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Upcoming SlideShare
jQuery勉強会#2
jQuery勉強会#2
Loading in …3
×

Check these out next

1 of 29 Ad

More Related Content

Recently uploaded (20)

Advertisement

ransack, ransack, ransack

  1. 1. Ransack, Ransack, Ransack Agileware kaigi 1 2014.7.25 @maimai77
  2. 2. Searching ActiveRecord! 一致検索はそこそこできる Issue.where(name: 'hoge').to_sql #=> "SELECT `issues`.* FROM `issues` WHERE `issues`.`name` = 'hoge'" Issue.where(name: ['hoge', 'fuga']).to_sql #=> "SELECT `issues`.* FROM `issues` WHERE `issues`.`name` IN ('hoge', 'fuga')"
  3. 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%')" 辛くなってきた…
  4. 4. Searching ActiveRecord ;< OR検索になるともうダメな子 4 Arel → 可読性 #とは 4 独自の検索クラス → 誰がメンテすんの? 4 生SQL → 心が折れそうだ…
  5. 5. Ransack
  6. 6. What is Ransack? ransack [rˈænsæk] 〈場所を〉くまなく探る[探す], あさり回る
  7. 7. What is Ransack? ransack gem https://github.com/activerecord-hackery/ransack 4 ActiveRecordを拡張して検索機能をつけるgem 4 設定なしで一通りの検索をカバー 4 high googleability → googleトップがgithub 4 ドキュメントが貧弱
  8. 8. How to use Ransack In your Gemfile: gem 'ransack' > bundle install Rails4, 4.1用に最適化されたbranchもある
  9. 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%')"
  10. 10. Search argument keys Issue.search(name_cont: 'hoge').result ransackable_attribute + predicate(述語) ex) 4 name_eq 4 name_cont
  11. 11. Ransackable_attributes Issue.ransackable_attributes #=> ["id", "name", "created_at", "updated_at"] defaultはIssue.column_namesと同じ
  12. 12. Predicates eq, gt, gteq, lt, lteq, in, cont, start, end and more https://github.com/activerecord-hackery/ransack/ wiki/Basic-Searching
  13. 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%')"
  14. 14. このあたりまではパーフ ェクトRuby on Railsにも ちらっと書いてます。
  15. 15. More Ransack
  16. 16. Complex search 4 2つのカラムのいずれかが指定した値と一致 4 関連先のテーブルを検索する
  17. 17. Complex search 4 2つのカラムのいずれかが指定した値と一致 Issue.ransack(name_or_memo_eq: 'hoge').result.to_sql #=> "SELECT `issues`.* FROM `issues` # WHERE ((`issues`.`name` = 'hoge' OR `issues`.`memo` = 'hoge'))" and, or で結合した ransackable_attribute も ransackable
  18. 18. Complex search 4 関連先のテーブルを検索する class Issue < ActiveRecord::Base belong_to :project end Issue.search(project_name_eq: 'hoge').result.to_sql #=> "SELECT `issues`.* FROM `issues` # LEFT OUTER JOIN `projects` ON `projects`.`id` = `issues`.`project_id` # WHERE `projects`.`name` = 'hoge'" association + ransackable_attribute も ransackable
  19. 19. More and more Ransack
  20. 20. More complex search 4 逆順の文字列と一致するものを検索 4 2つのカラムの値を結合したものと比較 4 半角スペースを無視した検索 組み合わせだけじゃなんとも… → ransacker
  21. 21. What is ransacker? customized ransackable_attribute ransackerメソッドで追加する
  22. 22. Define ransacker 4 逆順の文字列と一致するものを検索 class Issue < ActiveRecord::Base ransacker :reversed_name, formatter: proc { |v| v.reverse } do |parent| parent.table[:name] end end Issue.search(reversed_name_eq: 'hoge').result.to_sql #=> "SELECT `issues`.* FROM `issues` WHERE `issues`.`name` = 'egoh'"
  23. 23. Define ransacker formatter: 検索に渡したvalueを加工する proc { |v| v.reverse }.call('hoge') #=> "egoh" block: 検索対象のカラムを決定する
  24. 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. 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'"
  26. 26. Define ransacker NamedFunctionはDB依存しがちなので注意 なんかいい方法あったら教えてください
  27. 27. Custom Predicate config/initializers/ransack.rb で定義 Ransack.configure do |config| config.add_predicate 'equals_diddly', arel_predicate: 'eq', formatter: proc { |v| "#{v}-diddly" }, validator: proc { |v| v.present? }, compounds: true, type: :string end 割愛。
  28. 28. Conclusion
  29. 29. Conclusion 4 機能として検索画面が必要ならとりあえずransack使う 4 複雑な検索が必要になっても生SQLに逃げない 4 Arelとはちょっと向き合う 4 view helperも色々できる 4 でもorの結合くらいwhereでできるようになって欲しい

×