Ruby on rails Rails对来自用户的where子句的输入进行清理和验证

Ruby on rails Rails对来自用户的where子句的输入进行清理和验证,ruby-on-rails,ruby,activerecord,Ruby On Rails,Ruby,Activerecord,我有下面的代码,我用它根据用户的搜索过滤帖子的结果。我如何确保参数存在、有效且经过消毒 Post.where("title LIKE ? AND cost >= ? AND cost <= ? AND status = 'open'", "%#{search_params[:keywords]}%", "#{search_params[:min] && !search_params[:min].empty? ? search_p

我有下面的代码,我用它根据用户的搜索过滤帖子的结果。我如何确保参数存在、有效且经过消毒

Post.where("title LIKE ? AND cost >= ? AND cost <= ? AND status = 'open'", "%#{search_params[:keywords]}%",
                    "#{search_params[:min] && !search_params[:min].empty? ? search_params[:min] : 0}",
                    "#{search_params[:max] && !search_params[:max].empty? ? search_params[:max] : 999999999}");

Post.where(“类似标题”和成本>=?和成本与往常一样,有几种方法可以做到这一点

在我看来,最好的方法是去做。帮助实现这个模式的好方法是,但是你也可以使用

其思想是表单对象进行验证,如果它无效,控制器可以呈现验证错误

如果您在web上搜索“Rails表单模型模式”或类似内容,您会发现更多的文章。下面是另一篇写得不错的文章:

另一方面,您可能希望将这个复杂的查询封装在一个范围内,或者(如果您的应用程序将要增长的话)甚至是一个查询对象中。请参阅一些更高级的模式,这些模式在更复杂的Rails应用程序中更具优势


关于输入的清理,只要您使用的是参数绑定而不是手动字符串连接,Rails就会自动清理输入以防止SQL注入。如果您想做更多的事情,比如从搜索查询中删除停止词或诸如此类的事情,您最好使用预先存在的搜索框架,例如,或者。

我将通过结合几个作用域和一些条件来解决这个问题:

# in your models/post.rb
scope :min_cost, ->(cost) {
  cost = 0 if cost.blank?
  where('cost >= ?', cost)
}
scope :max_cost, ->(cost) {
  cost = 999_999_999 if cost.blank?
  where('cost <= ?', cost)
}
scope :cost_between, ->(min, max) { min_cost(min).max_cost(max) }
scope :open, -> { where(status: 'open') }
scope :search, ->(title) { where("title LIKE ?", "%#{title}%") if title }
\sanitize\u sql\u for\u conditions
方法应该在这里派上用场-
Post.open.search(search_params[:keywords])
        .cost_between(search_params[:min], search_params[:max])