ruby-on-rails – Ransack,找到包含所有相关记录的记录

前端之家收集整理的这篇文章主要介绍了ruby-on-rails – Ransack,找到包含所有相关记录的记录前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个配方模型,其中包含很多成分,每种成分都属于一个项目.在我的高级搜索表单中,我希望用户选择多种成分,让Ransack找到包含用户选择的所有成分的配方.

我尝试了以下搜索字段:

= f.collection_select(:ingredients_item_id_in,Item.all,:id,:name,{},{multiple: true})

但从逻辑上讲,这会导致显示的所有配方都含有任何选定的成分.

更改:ingredients_item_id_in到:ingredients_item_id_in_all会导致查询不正确,因为一条记录不能包含多个item_id值.

有关在Ransack中创建此搜索参数的任何想法,还是应该为此创建子查询

根据要求,我的控制器搜索方法

def search
    @q = Recipe.ransack(params[:q])
    @recipes = @q.result(distinct: true).include_related_models.published
  end

解决方法

我最近遇到了类似的项目任务(Rails 4.2.4 / Ruby 2.3.1).

Estate有许多舒适.我需要得到所有的庄园,其中包括所有选定的舒适.

以下是我使用Ransack解决它的方法

在我的情况下,我有has_many:通过关系.

estate.rb

class Estate < ActiveRecord::Base
  has_many :estate_comforts
  has_many :comforts,through: :estate_comforts
end

comfort.rb

class Comfort < ActiveRecord::Base
  has_many :estate_comforts
  has_many :estates,through: :estate_comforts
end

estate_comfort.rb

class EstateComfort < ActiveRecord::Base
  belongs_to :estate
  belongs_to :comfort
end

对于复杂查询,您需要通过帖子进行搜索.为此你必须编辑这样的路线.并将搜索操作添加到estates_controlle.rb.有关更多信息,请阅读Ransack wiki

的routes.rb

...
resources :estates
  collection do
    match 'search' => 'estates#search',via: %i[get post],as: :search
  end
end

estates_controller.rb

class EstatesController < ApplicationController
  ...

  def index
    @q = Estate.ransack(params[:q])

    @estates =
      if params[:q]&.has_key?(:estate_comforts_comfort_id_eq_any)
        # Store checked comforts
        session[:estate_comforts_comfort_id_eq_any] = params[:q][:estate_comforts_comfort_id_eq_any]

        comforts_count = params[:q][:estate_comforts_comfort_id_eq_any].count
        ids = @q.result.includes(:estate_comforts).group_by(&:id).select { |_,v| v.count == comforts_count}.keys
        Estate.where(id: ids)
      else
        @q.result(distinct: true)
      end
  end

  def search
    index
    render :index
  end
end

最后是模板部分……

庄园/ index.haml

= search_form_for @q,url: search_estates_path,html: { method: :post } do |f|
  # here goes the form inputs

  # Polulate checkBoxes with prevIoUsly checked comforts 
  - Comfort.find_each do |comfort|
    # Was checked prevIoUsly?
    - checked = comfort.id.to_s.in?(session[:estate_comforts_comfort_id_eq_any].to_a)
    %div  
      %input{ name: 'q[estate_comforts_comfort_id_eq_any][]',type: "checkBox",id: "checkBox#{comfort.id}",value: comfort.id,checked: checked }
        %label{for: "checkBox#{comfort.id}"}= comfort.name

生成以下html

<form class="estate_search" id="estate_search" action="/estates/search" accept-charset="UTF-8" method="post">
  <div>
    <input checked="" id="checkBox1" name="q[estate_comforts_comfort_id_eq_any][]" type="checkBox" value="1">
    <label for="checkBox1">Comfort Name 1</label>
  </div>
  <div>
    <input id="checkBox2" name="q[estate_comforts_comfort_id_eq_any][]" type="checkBox" value="2">
    <label for="checkBox2">Comfort Name 2</label>
  </div>
</form>

猜你在找的Ruby相关文章