Rails使用别名查询连接关联表
我有一个模型Edge
通过不同的外键两次属于另一个模型Node
:
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
我找到了使用.joins()
方法加入关联的方法:
Edge.joins(:first)
但这会产生使用表名而不是关联名的查询,所以在.where()
方法中我必须显式地使用表名来破坏关联抽象。
Edge.joins(:first).where(nodes: {value: 5})
我还可以在.joins()
方法中明确使用SQL查询来定义模型别名:
Edge.joins('INNER JOIN nodes as first ON nodes.id = edges.first_id')
但这打破了更多的抽象。
我认为应该有一种方法来自动定义连接上的表别名。 或者也许是一种自己编写这种function的方法。 就像是:
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已经在它的第四个主要版本上也是如此复杂。 也许我错过了什么?
至于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
- 显示从数据库到现在最近的未来时间
- 如何使用searchkick gem在rails中映射多个属性
- echo $ PATH与.bash_profile不匹配
- uninitialized constant> ActionCable :: Server :: Configuration :: ApplicationCable
- 安装调试器时出错:无法使用ruby-1.9.3-p362构建gem本机扩展
- PG :: ConnectionBad FATAL:角色“Myname”不存在
- Michael Hartl的Ruby on Rails教程,toy_app用户导览
- DataMapper有n通过资源DELETE(从关联中删除)不起作用
- 如何将主键添加到rails中的表