搜索用户配置文件

Search user profile with ransack

我有两个模型,userprofile。该用户有一份个人资料。

# profile.rb
class Profile < ActiveRecord::Base
  belongs_to :user
end

# user.rb
class User < ActiveRecord::Base
  has_one :profile
end

# routes.rb
resources :users do
  resource :profiles, except: [:index, :show]
end

# users_controller.rb
class UsersController < ApplicationController
  def index
    @users = User.includes(:profile)
  end
end

# users/index.html.erb
<% @users.each do |user| %>
  <% if user.profile %>
    <%= user.name %>
    <%= user.interest %>
  <% end %>
<% end %>

现在,我想添加 ransack gem 来搜索用户个人资料。这是我当前的设置:

# routes.rb
resources :users do
  collection do
      match 'search' => 'users#search', via: [:get, :post], as: :search
  end
  resource :profile, except: [:index, :show]
end

# users_controller.rb
class UsersController < ApplicationController
  def index
    @search = User.ransack(params[:q])
    @users = @search.result.includes(:profile)
  end

  def search
    index
    render :index
  end
end

# users/index.html.erb
<%= search_form_for @search, url: search_users_path, method: :post, do |f| %>
  <%= f.search_field :name_cont, placeholder: 'Name' %><br>
  <%= f.search_field :interest_cont, placeholder: 'Hobby' %><br>
  <%= f.submit 'Search %>
<% end %>

但是我得到了这个错误:

NoMethodError in Users#index

undefined method `name_cont' for Ransack::Search<class: User, base: Grouping <combinator: and>>:Ransack::Search

<%= f.search_field :name_cont, placeholder: 'Name' %><br>

我的代码有什么问题?我应该将搜索路径嵌套到配置文件而不是用户,所以它看起来像这样:

# routes.rb
resources :users do
  resource :profile, except: [:index, :show] do
    match 'search' => 'profiles#search', via: [:get, :post], as: :search
  end
end

那么,剩下的怎么设置呢?谢谢。

您需要将 ransacker 方法添加到您的用户模型中。可以找到示例 here

在User.rb

ransacker :name_cont, formatter: proc { |v|
  data = User.joins(:profile).where('profile.name = ?', v).map(&:id)
  data = data.present? ? data : nil
}, splat_param: true do |parent|
 parent.table[:id]
end

我没有测试过这段代码。

我的错误,我没有仔细阅读文档。我只需要在视图中使用这些:

<%= search_form_for @search, url: search_users_path, method: :post, do |f| %>
  <%= f.search_field :profile_name_cont, placeholder: 'Name' %><br>
  <%= f.search_field :profile_interest_cont, placeholder: 'Hobby' %><br>
  <%= f.submit 'Search %>
<% end %>