【问题标题】:Can you use association extensions on an object with custom finder_sql?您可以在具有自定义 finder_sql 的对象上使用关联扩展吗?
【发布时间】:2012-12-26 22:10:54
【问题描述】:

我的印象是 ActiveRecord 中的 custom_finder 选项意味着您可以免费获得 .where.order 等关联扩展,例如:

class Dog < ActiveRecord::Base
  has_many :fleas, class_name: 'Flea', 
           finder_sql: "select fleas.* from fleas where pet_type = 'dog'"
end

当然这不是一个很好的例子,因为“finder_sql”是如此微不足道,但它说明了这一点。

生成的 SQL

我会期待以下

@dog = Dog.find(5)
@dog.fleas.where('num_legs > 2')

生成

"select fleas.* from fleas where pet_type = 'dog' AND num_legs > 2

即自定义finder_sql + where子句

然而它实际生成的是

"SELECT "base_posts".* FROM "fleas" WHERE "fleas"."dog_id" = 5 AND (num_legs > 2)

即它完全忽略了自定义finder_sql 并尝试将跳蚤加入当前的狗。

如果自定义 finder_sql 不会导致关联扩展尊重它,那么它有什么意义 - 它可能只是对象上的一个方法...

【问题讨论】:

    标签: ruby-on-rails activerecord finder-sql


    【解决方案1】:

    这是真的。我认为自定义查找器是 Rails 中上一代查找器的遗产(在 Arel && AR::Relation 之前),它今天在关联中的存在只是为了向后兼容(恕我直言)。无论如何,它不符合 AR::Relation(扩展)的意识形态。

    现在,我们有 .find_by_sql():finder_sql 作为关联选项。

    其实现在当关联有:finder_sql 选项时,它只用于形成记录集合(使用.find_by_sql)。关联创建 AR::Relation 对象,加载集合 (.target) 并将 AR::Relation 方法调用委托给关系对象,但是它不知道任何自定义 SQL 语句并且只知道主 SQL 表达式。这就是为什么:

    @dog.fleas.class
    #=> Array
    @dog.fleas.to_sql # delegated to AR::Relation
    

    返回主要表达式 "SELECT "base_posts".* FROM..." 和

    @dog.fleas.where("...") # delegated to AR::Relation
    

    施加新条件,就好像没有自定义查找器一样。

    另一方面,由于 .find_by_sql 总是返回一个数组,因此可以使用 Array 的方法来施加新的条件。

     @dog.fleas.select {|r| ... } # delegated to Array
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-08
      • 1970-01-01
      • 1970-01-01
      • 2018-02-14
      相关资源
      最近更新 更多