如何正确选择连接表中的字段?

时间:2016-10-14 06:30:59

标签: ruby-on-rails ruby-on-rails-4 activerecord rails-activerecord

这是我的简化模型,我加入了模型,

模型公寓

   has_many :towers

模型塔

   belong_to :apartment

然后我试图加入控制器中的两个表也尝试在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 console中获得的最新结果:

 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">]>

如您所见,上面的查询只返回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">

... ETCC

4 个答案:

答案 0 :(得分:7)

我看到这一点的唯一方法是使用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方法不是为了显示非列属性而设计的。因此,即使您在内存中有塔名,它也只会显示属于公寓模型列的属性。 有关inspect

的更多信息

我还建议您尝试以下操作:

Apartment.joins(:towers).pluck('apartments.id, apartments.name, towers.id as t_id, towers.name as t_name')

上面的语句将获取数组中的所有数据。 select得到的结果与select相同,不会加载数组中的所有数据。

答案 1 :(得分:6)

你应该使用

Apartment.joins(:towers).select('apartments.id, apartments.name, towers.id , towers.name')

这是单个字符串中的所有列名。

Refer this.

答案 2 :(得分:0)

您可以尝试下面的别名

Apartment.joins(:towers).select('apartments.id as apartment_id, apartments.name as apartment_name, towers.id as tower_id , towers.name as tower_name)

答案 3 :(得分:0)

您可以尝试

Apartment.joins(:towers).select('apartments.id为id,apartments.name为apartment_name,towers.id为tower_id,towers.name为tower_name)

您将收到这样的响应 #ActiveRecord :: Relation [#, #<公寓ID:126,apt_name:“ mediterania”,tower_id:15,tower_name:“ Tower F“>]>