Nom*_*Nom 9 activerecord ruby-on-rails ruby-on-rails-4 rails-activerecord
这是我的简化模型,我加入了模型,
样板房
has_many :towers
Run Code Online (Sandbox Code Playgroud)
和
模型塔
belong_to :apartment
Run Code Online (Sandbox Code Playgroud)
然后我试图加入控制器中的两个表也尝试在rails控制台,如下所示:
Apartment.joins(:塔).select('apartments.id','apartments.name','towers.id','towers.name')
问题是上面的查询只返回
apartments.id和apartments.name
也尝试使用这样的别名,仍然没有运气
Apartment.joins(:塔).select('apartments.id','apartments.name','towers.id as towerid','towers.name as towername')
我已经确认所有塔楼都有公寓,我知道我可以做到这一点来获得1条记录
Apartment.joins(:塔).select('apartments.id','apartments.name','towers.id','towers.name').first.towers.id
等等,但我需要所有记录和所有这些字段,请咨询.
这是我在rails控制台中获得的最新结果:
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">]>
Run Code Online (Sandbox Code Playgroud)
如你所见,上面的查询只返回2个字段,我需要结果如下:
#<Apt id: 126, apt_name: "mediterania", tower_id: 12, tower_name: "tower A">,
#<Apt id: 126, apt_name: "mediterania", tower_id: 15, tower_name: "tower F">
Run Code Online (Sandbox Code Playgroud)
ETCC ...
我看到这一点的唯一方法就是使用 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
Run Code Online (Sandbox Code Playgroud)
为什么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">]>
Run Code Online (Sandbox Code Playgroud)
您在控制台中看到的结果是inspsect方法返回的结果.该inspect方法不是为了显示非列属性而设计的.因此,即使您在内存中有塔名,它也只会显示属于公寓模型列的属性.
更多关于 检查
我还建议尝试以下方法:
Apartment.joins(:towers).pluck('apartments.id, apartments.name, towers.id as t_id, towers.name as t_name')
Run Code Online (Sandbox Code Playgroud)
上面的语句将获取数组中的所有数据.select得到的结果与select相同,不会加载数组中的所有数据.
你应该用
Apartment.joins(:towers).select('apartments.id, apartments.name, towers.id , towers.name')
Run Code Online (Sandbox Code Playgroud)
这是单个字符串中的所有列名.
Rails 7.1添加了对此类查询的支持,现在select接受哈希
您可以像这样使用别名
Apartment
.joins(:towers)
.select(
apartments: { id: :apartment_id, name: :apartment_name },
towers: { id: :tower_id, name: :tower_name }
)
Run Code Online (Sandbox Code Playgroud)
它产生这样的查询
Apartment
.joins(:towers)
.select(
apartments: { id: :apartment_id, name: :apartment_name },
towers: { id: :tower_id, name: :tower_name }
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10976 次 |
| 最近记录: |