【问题标题】:What is the purpose of ActiveRecord::Relation#bind?ActiveRecord::Relation#bind 的目的是什么?
【发布时间】:2013-02-04 06:58:16
【问题描述】:

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

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

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

更新

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

【问题讨论】:

    标签: ruby-on-rails rails-activerecord relation


    【解决方案1】:

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

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

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

    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 列表中,然后返回新对象。最终,当关系用于生成查询时,该值将发现自己被用于进行查询。一个example,其中bind_values 被传递给find_by_sqlexec_queries 方法中:

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

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

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

    【讨论】:

    • 谢谢,但我已经想通了(请参阅我的问题的“更新”部分)-尽管努力 +1。我同意你的看法,它可能是剩菜;另一个假设是,该工具适用于需要它的特定适配器。至于在 postgres 适配器的源代码中徘徊,我还没有看到它实际使用这些值。我尝试了一些类似Model.where( "field = ?" ).bind( value ).to_sql 的方法,但绑定值没有出现在查询中。所以我猜它可能会被一些适配器用来构建准备好的(预编译)语句?
    • 我不会说这是一个完整的答案,但你是唯一尝试过的人,所以赏金是给你的。还是谢谢
    • 谢谢!对不起,我想不出更多的东西。我想你可以问问 Rails 的维护者。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-23
    相关资源
    最近更新 更多