Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays Rails 3动态转义查询绑定变量数量错误_Arrays_Ruby On Rails 3_Dynamic - Fatal编程技术网

Arrays Rails 3动态转义查询绑定变量数量错误

Arrays Rails 3动态转义查询绑定变量数量错误,arrays,ruby-on-rails-3,dynamic,Arrays,Ruby On Rails 3,Dynamic,我有一个表格,用户可以使用多种不同类型的组合以多种方式进行过滤。对于我从用户那里获得的所有输入数据,从SQL中转义用户数据对我来说很重要,这导致了我现在遇到的问题。我有两个数组,它们是基于发送到操作的参数动态构建的,一个数组包含SQL子句,另一个包含要与其各自的caluse配对的值。。。比如说 def results sql_clauses = Array.new sql_args = Array.new unless params[:elapsed_time].nil?

我有一个表格,用户可以使用多种不同类型的组合以多种方式进行过滤。对于我从用户那里获得的所有输入数据,从SQL中转义用户数据对我来说很重要,这导致了我现在遇到的问题。我有两个数组,它们是基于发送到操作的参数动态构建的,一个数组包含SQL子句,另一个包含要与其各自的caluse配对的值。。。比如说

def results

  sql_clauses = Array.new
  sql_args = Array.new

  unless params[:elapsed_time].nil?
    sql_clauses << "elapsed_time = ?"
    sql_args << params[:elaped_time] 
  end
  unless params[:age_greater_than].nil?
    sql_clauses << "age > ?"
    sql_args << params[:age_greater_than]
  end
  .....
  @results = Model.where(sql_clauses.join(" and "), sql_args.join(", "))

end
现在,这会将sql_子句数组发送到where方法,没有问题。但是它在第二个参数上爆炸了,因为它返回一个字符串,并且它期望与每个参数对应的单个变量?出现在sql_子句数组中的字段。我试过Kandaboggu提供的解决方案。虽然这两个选项对我都不起作用,但可能是因为我使用的是2个数组,而不是1个


有人知道我的问题的解决办法吗

试试这样的方法:

def results
  sql_clauses = []
  sql_clauses << "elapsed_time = :elapsed_time" if params[:elapsed_time]
  sql_clauses << "age > :age_greater_than" if params[:age_greater_than]
  .....
  @results = Model.where(sql_clauses.join(" and "), params)
end
map = {
   :elapsed_time => "elapsed_time =",
   :age_greater_than => "age >"
}

然后循环遍历params键,如果它们存在于map中,则构建子句。

尝试以下操作:

def results
  sql_clauses = []
  sql_clauses << "elapsed_time = :elapsed_time" if params[:elapsed_time]
  sql_clauses << "age > :age_greater_than" if params[:age_greater_than]
  .....
  @results = Model.where(sql_clauses.join(" and "), params)
end
map = {
   :elapsed_time => "elapsed_time =",
   :age_greater_than => "age >"
}

然后循环遍历params键并构建子句(如果它们存在于map中)。

在Rails 3中构建动态查询不需要使用字符串。ActiveRecord方法(如select、where、order、limit等)返回ActiveRecord::Relation对象,这些对象可以在不触发多个数据库调用的情况下链接:

cars=Car.where:color=>“black”此处不生成数据库查询。 rich\u ppls\u cars=cars.order'cars.price DESC'。limit10仍然没有数据库查询。 在调用ActiveRecord::Relation对象上的.all、.first、.last或.each时,将查询数据库

示例代码

假设您正在查询具有以下列的模型:

名称 经过的时间 年龄 您有一个如下所示的params散列:

def results
  sql_clauses = []
  sql_clauses << "elapsed_time = :elapsed_time" if params[:elapsed_time]
  sql_clauses << "age > :age_greater_than" if params[:age_greater_than]
  .....
  @results = Model.where(sql_clauses.join(" and "), params)
end
map = {
   :elapsed_time => "elapsed_time =",
   :age_greater_than => "age >"
}
{:已用时间=>34,:年龄=>14,:最大行=>20} 您的控制器操作可能如下所示:

def results
  sql_clauses = []
  sql_clauses << "elapsed_time = :elapsed_time" if params[:elapsed_time]
  sql_clauses << "age > :age_greater_than" if params[:age_greater_than]
  .....
  @results = Model.where(sql_clauses.join(" and "), params)
end
map = {
   :elapsed_time => "elapsed_time =",
   :age_greater_than => "age >"
}
def结果 query=ModelName。选择[:name,:已用时间,:age] query=query.where:appeased_time=>params[:appeased_time],如果params[:appeased_time]。是否存在? query=query.where'age>?',如果参数为[:age\u greater\u then],则参数为[:age\u greater\u than]。是否存在? query=query.limitparams[:max\u rows]如果参数[:max\u rows]。是否存在? @动态查询=查询 终止 请注意,我正在使用.present?测试参数键是否存在?。这可以防止我们将params散列中的空白字符串误解为有效数据

标准物质


在Rails3中,不需要使用字符串来构建动态查询。ActiveRecord方法(如select、where、order、limit等)返回ActiveRecord::Relation对象,这些对象可以在不触发多个数据库调用的情况下链接:

cars=Car.where:color=>“black”此处不生成数据库查询。 rich\u ppls\u cars=cars.order'cars.price DESC'。limit10仍然没有数据库查询。 在调用ActiveRecord::Relation对象上的.all、.first、.last或.each时,将查询数据库

示例代码

假设您正在查询具有以下列的模型:

名称 经过的时间 年龄 您有一个如下所示的params散列:

def results
  sql_clauses = []
  sql_clauses << "elapsed_time = :elapsed_time" if params[:elapsed_time]
  sql_clauses << "age > :age_greater_than" if params[:age_greater_than]
  .....
  @results = Model.where(sql_clauses.join(" and "), params)
end
map = {
   :elapsed_time => "elapsed_time =",
   :age_greater_than => "age >"
}
{:已用时间=>34,:年龄=>14,:最大行=>20} 您的控制器操作可能如下所示:

def results
  sql_clauses = []
  sql_clauses << "elapsed_time = :elapsed_time" if params[:elapsed_time]
  sql_clauses << "age > :age_greater_than" if params[:age_greater_than]
  .....
  @results = Model.where(sql_clauses.join(" and "), params)
end
map = {
   :elapsed_time => "elapsed_time =",
   :age_greater_than => "age >"
}
def结果 query=ModelName。选择[:name,:已用时间,:age] query=query.where:appeased_time=>params[:appeased_time],如果params[:appeased_time]。是否存在? query=query.where'age>?',如果参数为[:age\u greater\u then],则参数为[:age\u greater\u than]。是否存在? query=query.limitparams[:max\u rows]如果参数[:max\u rows]。是否存在? @动态查询=查询 终止 请注意,我正在使用.present?测试参数键是否存在?。这可以防止我们将params散列中的空白字符串误解为有效数据

标准物质


这对SQL注入安全吗?是的,我想是的,为什么不试试?User.where:a,{:a=>\a\}->SELECT users.*来自用户'where'\a\'`嘿,Mattias,不幸的是,对于一些参数,需要进行一些额外的处理,我不能接受它们作为参数进入我的查询。但我不知道你可以像那样传递整个params散列,我想知道这肯定很有用。我的一位同事推荐了一个更适合我的选项,他会很快分享他的答案。这对SQL注入安全吗?是的,我想是的,为什么不试试?User.where:A,{:A=>\A\}->SELECT users.*来自用户'where'\A\'嘿,Mattias,不幸的是,对于某些参数,需要进行一些额外的处理,我不能接受它们作为参数进入我的查询。但我不知道你可以像那样传递整个params散列,我想知道这肯定很有用。我的一位同事推荐了一个对我更有效的选择,他很快会分享他的答案。是的,这正是我最终的结果
实施。谢谢你的详细帖子。是的,这正是我最终实现的。谢谢你的详细帖子。