2015-03-31 82 views
13

我有過不同的外鍵屬於其他模型Node兩次模型EdgeRails的查詢加入關聯表別名爲

def Edge < ActiveRecord::Base 
    belongs_to :first, class_name: 'Node' 
    belongs_to :second, class_name: 'Node' 
end 

而且我想使用ActiveRecord執行此查詢:

SELECT * FROM edges INNER JOIN nodes as first ON first.id = edges.first_id WHERE first.value = 5 

我找到了加入關聯的方式,使用方法:

Edge.joins(:first) 

但是這會產生查詢使用表名稱,而不是關聯名稱,所以在.where()方法我必須顯式使用表名稱打破關聯抽象。

Edge.joins(:first).where(nodes: {value: 5}) 

我也可以明確地使用SQL查詢中.joins()方法來定義模型別名:

Edge.joins('INNER JOIN nodes as first ON nodes.id = edges.first_id') 

但是,這打破了更加抽象。

我認爲應該有辦法自動定義連接上的表別名。或者也許是我自己編寫這樣的函數的一種方法。喜歡的東西:

def Edge < ActiveRecord::Base 
    ... 
    def self.joins_alias 
     # Generate something like 
     # joins("INNER JOIN #{relation.table} as #{relation.alias} ON #{relation.alias}.#{relation.primary_key} = #{table}.#{relation.foreign_key}") 
    end 
end 

但我找不到任何關於有關訪問像它的名字特定的關係,外鍵,信息的任何信息等等。所以我該怎麼辦呢?

此外,即使通過Rails已經在其第四個主要版本中,這種明顯的特徵也是如此複雜,這似乎很奇怪。也許我錯過了什麼?

回答

5

至於Rails 4.2.1,我相信你在使用ActiveRecord中的joins時不能提供別名。

如果你想第一點查詢的邊緣,你可以做到這一點,就像你說:

Edge.joins(:first).where(nodes: {value: 1}) 
SELECT "edges".* FROM "edges" INNER JOIN "nodes" ON "nodes"."id" = "edges"."first_id" WHERE "nodes"."value" = 1 

但如果你有使用兩個節點進行查詢,你仍然可以使用joins這樣的:

Edge.joins(:first, :second).where(nodes: {value: 1}, seconds_edges: {value: 2}) 
SELECT "edges".* FROM "edges" INNER JOIN "nodes" ON "nodes"."id" = "edges"."first_id" INNER JOIN "nodes" "seconds_edges" ON "seconds_edges"."id" = "edges"."second_id" WHERE "nodes"."value" = 1 AND "seconds_edges"."value" = 2