7

只是出于好奇-我正在阅读Relation::QueryMethods 模块的文档并找到了该方法:

def bind(value)
  relation = clone
  relation.bind_values += [value]
  relation
end

有谁知道这是什么?我试图自己找到,但失败了。

更新

我追踪@bind_values到了无底深度的使用ActiveRecord::ConnectionAdapters——这些值一直传递下去,直到低级 SQL 语句执行。似乎各个适配器可能会使用这些。我的猜测是它与准备好的语句有关SELECT * FROM 'table' WHERE 'field' = ?,但我被困在这里。任何人?

4

1 回答 1

9

首先解释一下ActiveRecord提供的find_by_sql方法。看起来这个方法可以像这样使用:

Post.find_by_sql("SELECT title FROM posts WHERE author_id = ?", [author_id])

第二个参数称为“绑定”,它是与查询中的问号相对应的变量数组。您确实想使用 binds 数组将参数插入到查询中,因为它避免了如果您自己进行绑定会发生的许多SQL 注入危险:

Post.find_by_sql("SELECT title FROM posts WHERE author_id = #{author_id}")

那么,这与 ActiveRecord::Relation 有何关系?AREL 的要点是,您可以通过调用 ActiveRecord::Relation 对象上的方法一次构建一点查询。有很多这样的方法,下面是它们的一些列表:

http://apidock.com/rails/v3.2.8/ActiveRecord/QueryMethods

因此,该bind方法通过克隆当前对象来创建一个新对象,将指定的对象添加value到 的列表中bind_values,然后返回新对象。最终,当关系用于生成查询时,该值将发现自己被用于进行查询。get 传递给的一个示例是在方法中:bind_valuesfind_by_sqlexec_queries

@records = eager_loading? ? find_with_associations : @klass.find_by_sql(arel, bind_values)

您可以在 gem 中搜索“bind_values”,activerecord您会发现几个类似的地方正在使用它。

我原以为该bind方法会被调用where,但它似乎没有在 activerecord 中的任何地方调用。也许它是旧设计的遗留物。我认为你不应该bind在你的应用程序中调用。

于 2013-02-21T17:11:38.357 回答