ActiveRecord :: Relation#bind的目的是什么?

m_x*_*m_x 7 ruby-on-rails relation rails-activerecord

出于好奇 - 我正在阅读Relation :: QueryMethods模块的文档,并发现该方法:

def bind(value)
  relation = clone
  relation.bind_values += [value]
  relation
end
Run Code Online (Sandbox Code Playgroud)

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

UPDATE

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

Dav*_*son 9

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

Post.find_by_sql("SELECT title FROM posts WHERE author_id = ?", [author_id])
Run Code Online (Sandbox Code Playgroud)

第二个参数称为"绑定",它是一个与查询中的问号对应的变量数组.您确实希望使用binds数组将参数插入到查询中,因为它可以避免在您自己执行绑定时发生的大量SQL注入危险:

Post.find_by_sql("SELECT title FROM posts WHERE author_id = #{author_id}")
Run Code Online (Sandbox Code Playgroud)

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

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

因此,该bind方法通过克隆当前的对象来生成新对象,将指定的内容添加value到列表中bind_values,然后返回新对象.最终,当关系用于生成查询时,该值将发现自己用于进行查询.一个例子,其中bind_values获得通过,以find_by_sqlexec_queries方法:

@records = eager_loading? ? find_with_associations : @klass.find_by_sql(arel, bind_values)
Run Code Online (Sandbox Code Playgroud)

您可以在activerecordgem中搜索"bind_values" ,您会发现几个类似的地方正在使用它.

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