导轨联接查询与别名关联表 [英] Rails query join association table with alias

查看:137
本文介绍了导轨联接查询与别名关联表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模型属于其他模型边缘 节点两次通过不同的外键:

I have a model Edge that belongs to the other model Node twice through different foreign keys:

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

和我想用的ActiveRecord执行此查询:

And I want to perform this query using ActiveRecord:

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

我发现使用加入协会的方式 .joins()方法:

Edge.joins(:first)

但是,这在。凡使用一个表名,而不是关联的名字,所以()办法我必须明确地使用它打破协会抽象的表名。<产生查询/ p>

But this produces query using a table name, not an association name, so in .where() method I have to explicitly use table name which breaks association abstraction.

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

我也可以明确地使用SQL查询在 .joins()方法来定义模型别名:

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

但是,这打破了更为抽象。

But this breaks even more abstraction.

我觉得应该有自动定义的连接表的别名的方式。或者,也许办法由我写这样的功能。是这样的:

I think there should be the way to automatically define table alias on join. Or maybe a way to write such function by myself. Something like:

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

但我无法找到关于访问喜欢它的名字特定的关系,外键等信息的任何信息,所以我该怎么办呢?

But I couldn't find any information about accessing information about specific relation like it's name, foreign key, etc. So how can I do it?

此外,它似乎很奇怪,我认为这种明显的特征是非常复杂的,即使通过Rails是其第四大版本了。也许我失去了一些东西?

Also it seems strange to me that such obvious feature is so complicated even through Rails is on its 4th major version already. Maybe I'm missing something?

推荐答案

至于Rails的4.2.1,我相信你利用ActiveRecord的加入时,就不能提供一个别名

As for Rails 4.2.1, I believe you just cannot provide an alias when using joins from ActiveRecord.

如果您想第一个节点来查询的边缘,你可以做到这一点,就像你说:

If you want to query edges by the first node, you could do it just like you stated:

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

但如果你有使用两个节点进行查询,你仍然可以使用加入是这样的:

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

这篇关于导轨联接查询与别名关联表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆