在Ruby on Rails中向原始SQL查询传递参数

16

我想使用Rails Active Record执行一个原生的SQL查询,但是我的查询需要一个参数,我找不到一个合适的方法来安全地将该参数传递到查询字符串中。查询如下:

def self.get_branches_by_workspace_name(workspace_name)
  branches = ActiveRecord::Base.connection.execute("
    select
      address,
      phone,
      email,
      services
    from branches as b, workspaces as w
    where b.workspace_id = w.id and w.name= :workspace_name", workspace_name).to_a
  return branches
end

我想传递一个名为“workspace_name”的参数。有什么帮助吗?

3个回答

12
在你的模型中添加这个方法。
  def self.execute_sql(*sql_array)     
   connection.execute(sanitize_sql_array(sql_array))
  end

这将允许您在AR模型中对任意SQL进行清理和执行。
然后运行类似以下的代码来执行SQL,返回一个哈希数组,每个哈希对应查询返回的一行数据。
ModelName.execute_sql("select address,phone,email,services from branches as b, workspaces as w 
    where b.workspace_id = w.id and w.name= ?", workspace_name)

# => [{"address"=>"...","phone"=>"...","email"=>"...","services"=>"..."}, ...]

为什么需要 sendsanitize_sql_array 方法是受保护的。 - Tonči D.

11

在您的模型之外:

ActiveRecord::Base.connection.execute(
  ApplicationRecord.sanitize_sql([query, { param_1: param_1, param_2: param_2 }])
)

"ApplicationRecord.sanitize_sql" 应该改为 "ActiveRecord::Base::sanitize_sql" 吗? - Greg Atkinson
在我看来,最好、最直接的答案是: - Garrett Simpson

5
在你的模型中,你可以这样做。
  sql_command = <<-SQL
    SELECT address, phone, email, services
    FROM branches as b, workspaces as w
    WHERE b.workspace_id = w.id and w.name = :workspace_name
  SQL

  connection.execute(
    sanitize_sql_for_assignment([sql_command, workspace_name: "whatever"])
  )

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接