And*_*tin 19 join ruby-on-rails associations
我有一个模型Edge属于另一个模型Node两次通过不同的外键:
def Edge < ActiveRecord::Base
belongs_to :first, class_name: 'Node'
belongs_to :second, class_name: 'Node'
end
Run Code Online (Sandbox Code Playgroud)
我想使用ActiveRecord执行此查询:
SELECT * FROM edges INNER JOIN nodes as first ON first.id = edges.first_id WHERE first.value = 5
Run Code Online (Sandbox Code Playgroud)
我找到了使用.joins()方法加入关联的方法:
Edge.joins(:first)
Run Code Online (Sandbox Code Playgroud)
但是这会使用表名而不是关联名来生成查询,所以在.where()方法中我必须显式地使用表名来破坏关联抽象.
Edge.joins(:first).where(nodes: {value: 5})
Run Code Online (Sandbox Code Playgroud)
我还可以在.joins()方法中明确使用SQL查询来定义模型别名:
Edge.joins('INNER JOIN nodes as first ON nodes.id = edges.first_id')
Run Code Online (Sandbox Code Playgroud)
但这打破了更多的抽象.
我认为应该有一种方法来自动定义连接上的表别名.或者也许是一种自己编写这种功能的方法.就像是:
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
Run Code Online (Sandbox Code Playgroud)
但是我找不到任何关于访问特定关系信息的信息,比如它的名字,外键等等.那么我该怎么做呢?
即使Rails已经在其第四个主要版本上,这个显而易见的功能也非常复杂.也许我错过了什么?
至于Rails 4.2.1,我相信你在使用joinsActiveRecord 时无法提供别名.
如果你想通过第一个节点查询边缘,你可以像你所说的那样进行:
Edge.joins(:first).where(nodes: {value: 1})
SELECT "edges".* FROM "edges" INNER JOIN "nodes" ON "nodes"."id" = "edges"."first_id" WHERE "nodes"."value" = 1
Run Code Online (Sandbox Code Playgroud)
但是如果你必须使用两个节点进行查询,你仍然可以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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9495 次 |
| 最近记录: |