在rails应用程序中使用Ransack搜索表单中关联的多对多关联

时间:2017-12-21 19:39:10

标签: ruby-on-rails ruby-on-rails-4 spree

在我的狂欢应用程序中,我为用户提供了基于ransack的搜索表单,如下所示

<%= search_form_for [:admin, @search], url: admin_users_url do |f| %>
      <div class="field">
        <%= f.label :email_cont, Spree.t(:email) %> <br>
        <%= f.text_field :email_cont, :class => 'fullwidth' %>
      </div>
      <div class="field">
        <%= f.label :first_name_cont, Spree.t(:first_name) %> <br>
        <%= f.text_field :first_name_cont, :class => 'fullwidth' %>
      </div>
      <div class="field">
        <%= f.label :last_name_cont, Spree.t(:last_name) %> <br>
        <%= f.text_field :last_name_cont, :class => 'fullwidth' %>
      </div>
      <div data-hook="admin_users_index_search_buttons">
        <%= button Spree.t(:search_users), 'search' %>
      </div>
 <% end %>

在我的控制器中我有

Spree::Admin::UsersController.class_eval do
  def index
    @users = Spree::User.all.order(:email).
      ransack(params[:q]).
      result.
      page(params[:page]).
      per(params[:per_page])
   end
end

现在,spree_user可以有多个角色,角色类由spree定义如下

module Spree
  class Role < Spree::Base
    has_many :role_users, class_name: "Spree::RoleUser", dependent: :destroy
    has_many :users, through: :role_users
  end
end

有一个表spree_roles_users将用户连接到角色。我想在搜索表单中添加一个下拉选择字段,列出所有至少有一个属于它的用户的角色,并使用指定的角色进行搜索。我知道我必须在表单中添加collection_select来添加角色下拉列表,但我不确定如何在此场景中使用它。我在表单中添加了以下内容

<%= f.collection_select :spree_roles_ids, Spree::Role.all, :id, :name %>

但它会出现错误undefined method 'spree_roles_ids' for #<Ransack::Search:0x00561a6a02a370>

我该如何解决这个问题?

谢谢

1 个答案:

答案 0 :(得分:1)

首先,您需要将spree_roles模型的User关联列入白名单 您可以在spree.rb

中添加以下代码来执行此操作
Rails.application.config.to_prepare do
  Spree.user_class.whitelisted_ransackable_associations.push('spree_roles')
end

现在以ransack格式

<%= f.collection_select :spree_roles_id_eq, Spree::Role.all, :id, :name %>

请注意我使用了spree_roles_id_eq代替spree_roles_id,因为你必须告诉你搜索你的匹配条件。 在这种情况下,我正在查询平等条款。

希望这有帮助。