这是我的简化模型,我已经加入了模型:
class Apartment < ApplicationRecord
has_many :towers
end
和
class Tower < ApplicationRecord
belong_to :apartment
end
然后我尝试在控制器中加入两个表。我也在 Rails 控制台中尝试过,如下所示:
Apartment.joins(:towers).select('apartments.id', 'apartments.name', 'towers.id' , 'towers.name')
问题是上面的查询只返回
公寓.id 和公寓.名称
也尝试过使用这样的别名,仍然没有成功
Apartment.joins(:towers).select('apartments.id', 'apartments.name',
'towers.id as towerid' , 'towers.name as towername')
我已确认所有塔楼都有公寓,我知道我可以这样做以获得 1 条记录
Apartment.joins(:towers).select('公寓.id', '公寓.name', 'towers.id' , 'towers.name').first.towers.id
等等,但我需要所有记录和所有这些字段,请提出建议。
这是我在 Rails 控制台中得到的最新结果:
Apartment Load (1.0ms) SELECT apartments.id, apartments.name, towers.id as towerid, towers.
tower_name as towername FROM `apartments` INNER JOIN `towers` ON `towers`.`apt_id` = `
apartments`.`id`
=> #<ActiveRecord::Relation [#<Apartment id: 5, name: "basura">, #<Apartment id: 5, apt_
name: "basura">, #<Apartment id: 124, name: "hydra">, #<Apartment id: 124, name: "hy
dra">, #<Apartment id: 126, name: "mediterania">, #<Apartment id: 126, name: "mediterania">, #<Apartment id: 142, name: "apartement gajah mada">, #<Apartment id: 142, name: "apartement gajah mada">]>
如你所见,上面的查询只返回2个字段,我需要的结果是这样的:
#<Apartment id: 126, name: "mediterania", tower_id: 12, tower_name: "tower A">,
#<Apartment id: 126, name: "mediterania", tower_id: 15, tower_name: "tower F">
等等...
我认为这是可能的唯一方法是使用
as
q = Apartment.joins(:towers).select('apartments.id, apartments.name, towers.id as t_id, towers.name as t_name')
q.first.t_id
q.first.t_name
为什么first.towers.id不起作用?
apartment.towers
将会返回ActiveRecord::Associations::CollectionProxy
。您可以将其视为塔的集合。在 SQL 查询中,您指的是 towers
表。但是当你运行apartment.towers.id时,你正在CollectionProxy对象上调用id,这是行不通的。您可以使用towers.first
获得第一座塔。
关于,
Apt Load (1.0ms) SELECT apts.id, apts.apt_name, towers.id as towerid, towers.
tower_name as towername FROM `apts` INNER JOIN `towers` ON `towers`.`apt_id` = `
apts`.`id`
=> #<ActiveRecord::Relation [#<Apt id: 5, apt_name: "basura">, #<Apt id: 5, apt_
name: "basura">, #<Apt id: 124, apt_name: "hydra">, #<Apt id: 124, apt_name: "hy
dra">, #<Apt id: 126, apt_name: "mediterania">, #<Apt id: 126, apt_name: "mediterania">, #<Apt id: 142, apt_name: "apartement gajah mada">, #<Apt id: 142, apt_name: "apartement gajah mada">]>
在控制台看到的是
inspsect
方法返回的结果。 inspect
方法并不是为了显示非列属性而设计的。因此,即使内存中有 towername,它也只会显示公寓模型的列属性。
更多关于检查
我还建议尝试以下方法:
Apartment.joins(:towers).pluck('apartments.id, apartments.name, towers.id as t_id, towers.name as t_name')
以上语句将获取数组中的所有数据。使用 select 得到的结果相同,但 select 不会加载数组中的所有数据。
你应该使用
Apartment.joins(:towers).select('apartments.id, apartments.name, towers.id , towers.name')
这是单个字符串内的所有列名称。
Rails 7.1 添加对此类查询的支持,现在
select
接受哈希
您可以像这样使用别名
Apartment
.joins(:towers)
.select(
apartments: { id: :apartment_id, name: :apartment_name },
towers: { id: :tower_id, name: :tower_name }
)
它产生这样的查询
SELECT apartments.id AS apartment_id, apartments.name AS apartments_name,
towers.id AS tower_id, towers.name AS tower_name
FROM apartments
INNER JOIN towers ON towers.apartment_id = apartments.id
您可以尝试使用如下的别名
Apartment.joins(:towers).select('apartments.id as apartment_id, apartments.name as apartment_name, towers.id as tower_id , towers.name as tower_name)
你可以试试这个
Apartment.joins(:towers).select('apartments.id 作为 id, 公寓.name 作为 Apartment_name, towers.id 作为 tower_id , towers.name 作为 tower_name)
你会得到这样的回复
#ActiveRecord::关系 [#