如何加入数据?
How can I join data?
我正在制作一个搜索条件页面。
我要的是,如果有多个条件搜索&&
,如果有空白字段,搜索不包括空白字段。
我当前的代码是:
name_sei = params[:nameSei]
name_mei = params[:nameMei]
email = params[:email]
tel = params[:tel].to_i
birth = params[:birth].to_i
job_area = params[:jobArea]
station = params[:station]
sex = params[:sex]
coordinator = params[:coordinator]
inflow_souce = params[:inflowSouce]
evaluation = params[:evaluation] || []
skill = params[:skill] || []
position = params[:position] || []
users =
User
.order('users.created_at DESC')
.includes(:evaluations, :skills, :positions)
.where('name_sei like ?', "%#{name_sei}%" && 'name_mei like ?', "%#{name_mei}%" && 'email like ?', "%#{email}%"....)
我的代码的问题是,如果该字段包含空白,rails 将包含 ""
并且搜索将失败。
所以我想出了这个代码:
users =
User
.order('users.created_at DESC')
.includes(:evaluations, :skills, :positions)
.where('name_sei like ?', "%#{name_sei}%") if params[:nameSei] != ''
users =
User
.order('users.created_at DESC')
.includes(:evaluations, :skills, :positions)
.where('name_mei like ?', "%#{name_mei}%") if params[:nameMei] != ''
我觉得如果那两个用户数据能join就好了。
但我不知道如何加入数据。
你能帮帮我吗?
谢谢。
与其在控制器中“内联”搜索功能,不如将其移出到单独的模型中:
# app/models/user_search.rb
# This is just a model to represent a search query
# its not actually saved to the database
class UserSearch
include ActiveModel::Model
include ActiveModel::Attributes
# @see https://api.rubyonrails.org/classes/ActiveModel/Attributes/ClassMethods.html
attribute :name_sei
attribute :name_mei
attribute :tel, :integer
attribute :birth, :integer # Use a date instead?
attribute :sex
# ... define the rest of the attributes you want to be able to filter by
# This just loops through the attributes of this model and
# filters the users based on it
# blank attributes are filtered out
#
# this will filter the results by using `WHERE x = y`
# you can easily override it on a per attribute basis by
# implementing a `filter_by_x` method
# that method should return a ActiveRecord::Relation or nil
# @param [ActiveRecord::Relation] base
# @return [ActiveRecord::Relation] the base scope with filters applied
def to_scope(base: User.all)
scopes = attributes.compact_blank do |attr, value|
if respond_to?("filter_by_#{attr}")
send("filter_by_#{attr}", value)
else
User.where(attr => value)
end
end
scopes.compact.inject(base) {|memo, item| memo.merge(item)}
end
private
def filter_by_name_sei(val)
User.where('"users"."name_sei" like ?', "%#{val}%")
end
def filter_by_name_mei(val)
User.where('"users"."name_mei" like ?', "%#{val}%")
end
end
这让您可以通过将搜索过滤器的散列传递给 class 来测试它的隔离,而不是创建一个完整的 HTTP 请求,然后编写关于来自控制器的响应的断言。您不必一定要将此功能放入模型中 - 这里的关键要点是不要只是将它放入您的控制器中,因为这将非常难以测试。
使用模型确实可以让您使用 ActiveModel 的所有优点,例如类型转换、默认值、验证、I18n 集成等
从您的控制器中,您可以使用强参数将参数传递给模型:
class UsersController
# GET /users
# GET /users?search[name_sei]=foo...
def index
@search = UserSearch.new(search_parameters)
@users = @search.to_scope(base: User.order(created_at: :desc))
end
private
def search_parameters
params.fetch(:search, {})
.permit(
:name_sei, :name_mei # ...
)
end
end
您只需创建一个绑定到模型的表单即可:
<%= form_with(model: @search, url: users_path, method: :get, scope: :search) do |form| %>
<div class="field">
<%= f.label :name_sei %>
<%= f.text_field :name_sei %>
</div>
# ...
<div class="actions">
<%= f.submit "Search" %>
</div>
<% end %>
我正在制作一个搜索条件页面。
我要的是,如果有多个条件搜索&&
,如果有空白字段,搜索不包括空白字段。
我当前的代码是:
name_sei = params[:nameSei]
name_mei = params[:nameMei]
email = params[:email]
tel = params[:tel].to_i
birth = params[:birth].to_i
job_area = params[:jobArea]
station = params[:station]
sex = params[:sex]
coordinator = params[:coordinator]
inflow_souce = params[:inflowSouce]
evaluation = params[:evaluation] || []
skill = params[:skill] || []
position = params[:position] || []
users =
User
.order('users.created_at DESC')
.includes(:evaluations, :skills, :positions)
.where('name_sei like ?', "%#{name_sei}%" && 'name_mei like ?', "%#{name_mei}%" && 'email like ?', "%#{email}%"....)
我的代码的问题是,如果该字段包含空白,rails 将包含 ""
并且搜索将失败。
所以我想出了这个代码:
users =
User
.order('users.created_at DESC')
.includes(:evaluations, :skills, :positions)
.where('name_sei like ?', "%#{name_sei}%") if params[:nameSei] != ''
users =
User
.order('users.created_at DESC')
.includes(:evaluations, :skills, :positions)
.where('name_mei like ?', "%#{name_mei}%") if params[:nameMei] != ''
我觉得如果那两个用户数据能join就好了。
但我不知道如何加入数据。
你能帮帮我吗?
谢谢。
与其在控制器中“内联”搜索功能,不如将其移出到单独的模型中:
# app/models/user_search.rb
# This is just a model to represent a search query
# its not actually saved to the database
class UserSearch
include ActiveModel::Model
include ActiveModel::Attributes
# @see https://api.rubyonrails.org/classes/ActiveModel/Attributes/ClassMethods.html
attribute :name_sei
attribute :name_mei
attribute :tel, :integer
attribute :birth, :integer # Use a date instead?
attribute :sex
# ... define the rest of the attributes you want to be able to filter by
# This just loops through the attributes of this model and
# filters the users based on it
# blank attributes are filtered out
#
# this will filter the results by using `WHERE x = y`
# you can easily override it on a per attribute basis by
# implementing a `filter_by_x` method
# that method should return a ActiveRecord::Relation or nil
# @param [ActiveRecord::Relation] base
# @return [ActiveRecord::Relation] the base scope with filters applied
def to_scope(base: User.all)
scopes = attributes.compact_blank do |attr, value|
if respond_to?("filter_by_#{attr}")
send("filter_by_#{attr}", value)
else
User.where(attr => value)
end
end
scopes.compact.inject(base) {|memo, item| memo.merge(item)}
end
private
def filter_by_name_sei(val)
User.where('"users"."name_sei" like ?', "%#{val}%")
end
def filter_by_name_mei(val)
User.where('"users"."name_mei" like ?', "%#{val}%")
end
end
这让您可以通过将搜索过滤器的散列传递给 class 来测试它的隔离,而不是创建一个完整的 HTTP 请求,然后编写关于来自控制器的响应的断言。您不必一定要将此功能放入模型中 - 这里的关键要点是不要只是将它放入您的控制器中,因为这将非常难以测试。
使用模型确实可以让您使用 ActiveModel 的所有优点,例如类型转换、默认值、验证、I18n 集成等
从您的控制器中,您可以使用强参数将参数传递给模型:
class UsersController
# GET /users
# GET /users?search[name_sei]=foo...
def index
@search = UserSearch.new(search_parameters)
@users = @search.to_scope(base: User.order(created_at: :desc))
end
private
def search_parameters
params.fetch(:search, {})
.permit(
:name_sei, :name_mei # ...
)
end
end
您只需创建一个绑定到模型的表单即可:
<%= form_with(model: @search, url: users_path, method: :get, scope: :search) do |form| %>
<div class="field">
<%= f.label :name_sei %>
<%= f.text_field :name_sei %>
</div>
# ...
<div class="actions">
<%= f.submit "Search" %>
</div>
<% end %>