2012-12-26 33 views
0

我的印象是,在ActiveRecord的该custom_finder选项意味着你有关联的扩展名如.where.order免费,例如:您可以使用自定义finder_sql在对象上使用关联扩展吗?

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不会导致联想扩展尊重它,然后什么在它一点 - 它可能只是在对象上的方法...

回答

0

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

到现在为止,我们已经.find_by_sql(),我们有:finder_sql作为协会的选项。

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

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

收益主要表达的 “选择 ”base_posts和

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

施加新的条件,如果没有自定义查找“ * FROM ...。”。

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

@dog.fleas.select {|r| ... } # delegated to Array 
相关问题