Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails, why joins returns array with non-uniq values?

I use example with Rails 3, but I believe that this is true for Rails 2.3 as well.

Suppose, I have model City that has many Locations. I try to find Cities that have locations.

I use following code:

City.joins(:locations)

But output array is:

=> [#<City id: 5, name: "moscow", created_at: "2010-07-02 15:09:16", updated_at: "2010-07-02 15:09:16">, #<City id: 5, name: "moscow", created_at: "2010-07-02 15:09:16", updated_at: "2010-07-02 15:09:16">, #<City id: 5, name: "moscow", created_at: "2010-07-02 15:09:16", updated_at: "2010-07-02 15:09:16">, #<City id: 5, name: "moscow", created_at: "2010-07-02 15:09:16", updated_at: "2010-07-02 15:09:16">]

Array length is 4 (number of locations of Moscow).

In what case it can be useful? For what aims are 4 copies of one object in output-array?

I can use City.joins(:locations).uniq, but I lost agile of arel.

I have two questions:

  1. Why joins returns non unique array?
  2. What is prefer to use instead of joins for this purpose?
like image 288
petRUShka Avatar asked Jul 04 '10 13:07

petRUShka


1 Answers

Join essentially says to combine two tables and treat it like one table, sending back whatever would be found. That means it will find you every combination of city and location (Rails is helping out by matching things up based on the belongs_to/has_many relationship in your models).

Doing City.joins(:locations) would be for finding all the locations in a city. Doing it the other way (Location.joins(:city)) would be for finding what city a location is in.

Now, to just find the list of cities that have some locations, you might try City.select(:city).joins(:locations).group('cities.id') The select() clause tells it to just bring back the City, and the group() clause tells it to not bring back duplicate copies.

like image 160
edebill Avatar answered Oct 22 '22 02:10

edebill