搜索用户配置文件
Search user profile with ransack
我有两个模型,user
和 profile
。该用户有一份个人资料。
# 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 %>
我有两个模型,user
和 profile
。该用户有一份个人资料。
# 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 %>