Ruby on rails 参数查询

Ruby on rails 参数查询,ruby-on-rails,Ruby On Rails,我想根据收到的参数获取记录。有时我收到2个参数,有时收到3个参数。我已经编写了一个代码,当所有3个参数都收到时得到结果,但当我只收到1个参数时,我得到0个结果 范例 Office.where(state: params[:state], type: params[:type]).where("name like ?","%#{params[:name]}%") 当我得到像 {state: "KA", type: "private", name: "google"} 但是当我得到唯一的{nam

我想根据收到的参数获取记录。有时我收到2个参数,有时收到3个参数。我已经编写了一个代码,当所有3个参数都收到时得到结果,但当我只收到1个参数时,我得到0个结果

范例

Office.where(state: params[:state], type: params[:type]).where("name like ?","%#{params[:name]}%")
当我得到像

{state: "KA", type: "private", name: "google"}
但是当我得到唯一的{name:“google”}时,我没有任何记录

我已经试过了

If params[:name].present? && params[:state].present? && params[:type].present?
query
elsif condition
query
end

让我知道我如何解决这个问题或任何更好的方法

您可以这样做

内部控制器

filter_params = params.slice(:state, :type, :name)
Office.filter(filter_params)
办公室中
型号

scope :state, -> (state) { where(state: state) }
scope :type, -> (type) { where(type: type) }
scope :name, -> (name) { where("name LIKE ?", "%#{name}%") }

def self.filter(filter_params)
  results = where(nil)
  filter_params.each do |key, value|
    results = results.public_send(key, value) if value.present?
  end
  results
end
PS:它运行单个查询,而不考虑参数的数量


希望有帮助

如果缺少参数,则该参数可能为空。如果将它们全部传入,则会产生类似
type=''
的子句。例如,如果只传入
name
,您将得到类似于

where name like '%google%' and type = '' and state = ''
你需要删去空白字段。有多种方法可以做到这一点。由于您有一个特例,
name
子句,处理这个问题的一个好方法是逐段构建查询

query = Office.all
query = query.where(state: params[:state]) if params[:state].present?
query = query.where(type: params[:type]) if params[:type].present?
query = query.where("name like ?","%#{params[:name]}%") if params[:name].present?
只有从
query
中获取值,查询才会执行

如果有很多简单的参数,您可以创建一个散列并删除具有空值的对

qparams = {
  state: params[:state],
  type: params[:type]
}.select { |k,v|
  v.present?
}

query = Office.where(qparams)
query = query.where("name like ?","%#{params[:name]}%") if params[:name].present?
或者使用方便的工具


您使用的Rails版本是什么?Rails 5.2.2和ruby 2.5.1您将根据需要和当前参数的数量进行三次查询或
n
。应该有更简单的方法。@SebastianPalma不,如果没有,它将运行一个查询。这就是Rails中ActiveRecord的美妙之处@Schwern它没有,必须定义范围。但现在它应该可以工作了@我喜欢使用示波器。使用
public\u send
会引发安全问题,如果不使用强参数,则可能会调用任何公共方法。我想知道是不是最好让示波器忽略空白<代码>范围:状态,->(状态){where(状态:状态)if state.present?}等。。。然后
Office.state(state).type(type).name(name)
@Schwern您在谈论什么安全问题?已经使用控制器中的
slice
对参数进行了所需参数的过滤。在
过滤器
方法中已经处理了空格。
using CompactBlank

qparams = {
  state: params[:state],
  type: params[:type]
}.compact_blank

query = Office.where(qparams)
query = query.where("name like ?","%#{params[:name]}%") if params[:name].present?