1

我知道如何將以下代碼轉換爲嚴格使用Arel方法,而不是混合sql/string,但我不知道如何將生成的arel對象合併到ActiveRecord :: Relation中,以便可以鏈接更多的AR :: Relation方法在上面。如何將一個arel對象合併到一個ActiveRecord :: Relation鏈中?

我得到了以下非常有幫助的回答我剛纔的問題:

class Address < ActiveRecord::Base 
    scope :anywhere, lambda{|search| 
    attrs = [:line1, :line2, :city, :state, :zip] 
    where(attrs.map{|attr| 
     "addresses.#{attr} LIKE :search" 
    }.join(' OR '), search: "#{search}%").order(*attrs) 
    } 
end 

Person.joins(:address).merge(Address.anywhere(query_term)) 

我試圖做這樣的事情:

class Address < ActiveRecord::Base 
    scope :anywhere, lambda{|search| 
    addr_arel = Address.arel_table 
    attrs = [:line1, :line2, :city, :state, :zip] 
    attrs.inject {|attr| 
     q = addr_arel[attr].match("%#{search}%") unless q 
     q = q.or(addr_arel[attr].match("%#{search}%") 
    } 
    } 
end 

但我最終的AREL對象,我不t知道如何合併它與以下ActiveRecord :: Relation:

Person.joins(:address).merge(Address.anywhere(query_term))

(更不用說注入也不是很優雅 - 我該如何改進?)

回答

2

ActiveRecord :: Relation.where接受ARel謂詞,因此在這種情況下,您可以直接將最終謂詞傳遞給Address.where。

class Address < ActiveRecord::Base 
    scope :anywhere, -> search { 
    addr_arel = Address.arel_table 
    attrs = [:line1, :line2, :city, :state, :zip] 

    where attrs 
     .map {|attr| addr_arel[attr].matches("%#{search}%")} 
     .inject(:or) 
    } 
end 
相關問題