here is my simplified models, i have joined models,
model apartment
has_many :towers
and
model tower
belong_to :apartment
and then i tried to join both tables in controller also tried it in rails console like this :
Apartment.joins(:towers).select('apartments.id', 'apartments.name', 'towers.id' , 'towers.name')
the problem is above query only returns
apartments.id and apartments.name
also tried to use alias like this, still no luck
Apartment.joins(:towers).select('apartments.id', 'apartments.name', 'towers.id as towerid' , 'towers.name as towername')
i have confirmed that all towers have an apartment, i know i could do this to get 1 record
Apartment.joins(:towers).select('apartments.id', 'apartments.name', 'towers.id' , 'towers.name').first.towers.id
and etc, but i need all records and all those fields, please advice.
here is the latest result i got in 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">]>
as you can see, above query only return 2 fields, i need the result to be like this :
#<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...
The only way I see this is possible is using 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
Why first.towers.id will not work?
apartment.towers
will return ActiveRecord::Associations::CollectionProxy
. You can think of it as a collection of towers. In SQL query you are referring to towers
table. But when you run apartment.towers.id you are calling id on CollectionProxy object which will not work. You can get first tower using towers.first
.
Regarding,
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">]>
What you see in console is result returned by inspsect
method. The inspect
method is not designed to show non column attributes. Hence even if you have towername in memory it will only show attributes which are columns of Apartment model.
More about inspect
I also recommend to try following:
Apartment.joins(:towers).pluck('apartments.id, apartments.name, towers.id as t_id, towers.name as t_name')
Above statement will get all data in array. The same result you get with select but select will not load all data in array.
You should use
Apartment.joins(:towers).select('apartments.id, apartments.name, towers.id , towers.name')
that is all column names inside a single string.
Refer this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With