11007


Rails4を使ってホテル検索システムのようなものを作成しています。  
そしてこのシステムの検索機能として、特定の設備を持つ（複数選択可）ホテルを検索して表示する、といったことをRansackを使って実装しようとしています。

例えば、検索画面にて「大浴場」、「レストラン」、「売店」などのチェックボックスを用意してチェックしてもらい、検索するようなシステムです。  
ここで問題なのですが、「大浴場」、「レストラン」、「売店」全てにチェックボックスにチェックして、これら３つ全てを持つホテルのみを検索させることができておりません。  
3つ全てにチェックしても、３つの内いずれかを持つホテルが表示される状況です。

どのようにしたら解決できるのか、ご教授頂きたいです。  
またそもそも前提がおかしいなどありましたらご指摘頂きたいです。  
詳細を以下に記載致します。  

* * *

app/model/hotel.rb

[code]

    # == Schema Information
    #
    # Table name: hotels
    #
    #  id            :integer          not null, primary key
    #  name          :string(50)       not null              # ホテル名
    #  address       :string(50)       not null              # ホテル住所
    #  created_at    :datetime
    #  updated_at    :datetime
    
    
    class Hotel < ActiveRecord::Base
      has_many :equipments,     dependent: :destroy
    end
    
[/code]

* * *

app/model/equipment.rb

[code]

    # == Schema Information
    #
    # Table name: equipments
    #
    #  id                    :integer          not null, primary key
    #  hotel_id              :integer          not null              # ホテルid
    #  equipmentlist_id      :integer          not null              # 設備リストid
    #  note                  :string(100)                            # 設備に関するメモ（利用可能時間等）
    #  created_at            :datetime
    #  updated_at            :datetime
    
    
    class Branch < ActiveRecord::Base
      belongs_to :company
      belongs_to :equipmentlist
    end
    
[/code]

* * *

app/model/equipmentlist.rb

[code]

    # == Schema Information
    #
    # Table name: equipmentlists
    #
    #  id                    :integer          not null, primary key
    #  name                  :string(50)       not null              # 設備名
    #  created_at            :datetime
    #  updated_at            :datetime
    class Equipmentlist < ActiveRecord::Base
    end
    
[/code]

* * *

app/controller/hotels_controller.rb

[code]

    class HotelsController < ApplicationController
    def index
        @q = Hotel.ransack(params[:q])
        @q.sorts = 'updated_at desc' if @q.sorts.empty?
        @hotels = @q.result.uniq.page(params[:page])
        @equipmentlists = Equipmentlist.all
    end
    
[/code]

* * *

app/views/index.html.erb（検索部分のみ抜粋）

[code]

    ...
    <ul>
     <% @equipmentlist.each do |item| %>
     <li>
       <%= f.check_box :equipments_equipmentlist_id_eq, { multiple: true }, item.id, nil %>
       <%= f.label item.name %>
     </li>
    <% end %>
    </ul>
    ...
    
[/code]

* * *

  
以上になります。  
なお、コンソールにて以下のようにすれば、目的の結果が得られるのですが、これをどうやってRansackで実現するのかわかっておりません。

[code]

    Equipment.where(Equipment.arel_table[:equipmentlist_id].in([8,10])).group(:hotel_id).having("count(*) = ?", 2)
    
[/code]

大変初歩的な質問かもしれませんが、どんなことでも結構ですので教えて頂ければ幸いです。  
よろしくお願い致します。


CC BY-SA 3.0
2015-06-05T06:04:29.043
11003
2015-06-05T08:51:34.007
9875
question
ruby-on-rails
Rails4でRansackを用いた検索にて複数のカテゴリ全てに所属するレコードを検索したい


おそらく、ransackのSimple Modeだけでは実現できないと思います。  
「チェックされた設備を全て持つ」という複雑な条件はscopeにしてしまえば良いと思います。  
scopeやクラスメソッドはransackから呼び出すことが出来ますし、単体テストもしやすくなります。

[Using Scopes/Class Methods](https://github.com/activerecord-
hackery/ransack#using-scopesclass-methods)  
[Ransack で ActiveRecord の Scope
を利用して検索を行う方法](http://qiita.com/ruzia/items/f6003547ca18377a1508)

以下の様なイメージになるかと思います。

app/model/hotel.rb

[code]

    class Hotel < ActiveRecord::Base
      has_many :equipments,     dependent: :destroy
    
      scope :having_all_equipmentlists_of, ->(equipmentlist_ids) {
        joins(xxx)
          .group(xxxx)
          .having(xxxx)
      }
    
      private
    
      def self.ransackable_scopes(auth_object = nil)
        %i(having_all_equipmentlists_of)
      end
    end
    
    ~~~~~
    
    Hotel.ransack({ having_all_equipmentlists_of: [8, 9, 10] }).result
    
[/code]

あとはチェックボックスのパラメータ名をscope名に合わせてあげれば良いかと。


CC BY-SA 3.0
2015-06-05T08:51:34.007
11007
2015-06-05T08:51:34.007
9608
11003
answer