Ruby on rails rails动态sql查询

Ruby on rails rails动态sql查询,ruby-on-rails,postgresql,rails-activerecord,ruby-on-rails-5,Ruby On Rails,Postgresql,Rails Activerecord,Ruby On Rails 5,我有一个对象,它有一组表示可搜索模型属性的属性,我想只使用设置的属性动态创建一个sql查询。我创建了下面的方法,但我相信它容易受到sql注入攻击。我做了一些研究并阅读了《rails活动记录查询接口指南》,但where条件似乎总是需要一个静态定义的字符串作为第一个参数。我还试图找到一种方法来清理由我的方法生成的sql字符串,但似乎也没有一种好的方法 我怎样才能做得更好?我应该使用where条件还是只是以某种方式清理这个sql字符串?谢谢 def query_string to_return =

我有一个对象,它有一组表示可搜索模型属性的属性,我想只使用设置的属性动态创建一个sql查询。我创建了下面的方法,但我相信它容易受到sql注入攻击。我做了一些研究并阅读了《rails活动记录查询接口指南》,但where条件似乎总是需要一个静态定义的字符串作为第一个参数。我还试图找到一种方法来清理由我的方法生成的sql字符串,但似乎也没有一种好的方法

我怎样才能做得更好?我应该使用where条件还是只是以某种方式清理这个sql字符串?谢谢

def query_string
  to_return = ""

  self.instance_values.symbolize_keys.each do |attr_name, attr_value|
    if defined?(attr_value) and !attr_value.blank?
      to_return << "#{attr_name} LIKE '%#{attr_value}%' and "
    end
  end
  to_return.chomp(" and ")
end
def查询\u字符串
to_return=“”
self.instance_values.symbol_key.each do|attr_name,attr_value|
如果定义?(属性值)和!属性值为空?

返回当你试图解决错误的问题时,你的方法有点不合适。您正在尝试构建一个字符串以交给ActiveRecord,以便它可以在您只需要尝试构建查询时构建查询

当你说这样的话:

Model.where('a and b')
def query
  self.instance_values.select { |_, v| v.present? }.inject(YourModel) do |q, (name, value)|
    q.where("#{name} like ?", "%#{value}%")
  end
end
这等于说:

Model.where('a').where('b')
你可以说:

Model.where('c like ?', pattern)
而不是:

Model.where("c like '#{pattern}'")
将这两个想法与你的
自我价值观相结合,你可以得到如下结果:

Model.where('a and b')
def query
  self.instance_values.select { |_, v| v.present? }.inject(YourModel) do |q, (name, value)|
    q.where("#{name} like ?", "%#{value}%")
  end
end
甚至:

def query
  empties      = ->(_, v) { v.blank? }
  add_to_query = ->(q, (n, v)) { q.where("#{n} like ?", "%#{v}%") }
  instance_values.reject(&empties)
                 .inject(YourModel, &add_to_query)
end

这些假设您已经正确地将所有实例变量列为白名单。如果你还没有,那么你应该。

哇,你的红宝石技能让我惊叹不已。第二个例子是头脑爆炸。谢谢