gpt4 book ai didi

ruby-on-rails - rails dynamic where sql 查询

转载 作者:行者123 更新时间:2023-11-29 12:57:17 24 4
gpt4 key购买 nike

我有一个对象,它有一堆表示可搜索模型属性的属性,我想只使用设置的属性动态创建一个 sql 查询。我创建了下面的方法,但我相信它容易受到 sql 注入(inject)攻击。我做了一些研究并阅读了 rails 事件记录查询接口(interface)指南,但似乎 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

最佳答案

您尝试解决错误的问题时,您的方法有点偏差。您正在尝试构建一个字符串以交给 ActiveRecord,以便它可以在您应该简单地尝试构建查询时构建查询。

当你说这样的话时:

Model.where('a and b')

这等同于说:

Model.where('a').where('b')

你可以说:

Model.where('c like ?', pattern)

代替:

Model.where("c like '#{pattern}'")

将这两个想法与您的 self.instance_values 相结合,您可以得到如下内容:

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

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

关于ruby-on-rails - rails dynamic where sql 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39939455/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com