views:

39

answers:

3

When fetching content from a database using activerecord, I would like to fetch a custom resultset with specified columns across two tables.

SELECT users.name, users.username, users.age, users.city_id, cities.name as city_name FROM users INNER JOIN cities ON users.city_id = cities.id

Which would be in AR as

Users.find(:all, 
   :joins => :cities, 
   :select => "users.name, users.username, users.age, users.city_id,
      cities.name as city_name")

But this only returns the user table results and not the city results. I am 100% sure that the inner join statement is going through (that both tables are being joined).

It seems as if the return object only has the columns associated with the model. So UserModel would only have the columns that the users table has and won't allow to fetch the columns of the cities table even though they're specified in the select.

Should I be using :joins or :include? Any idea what's going on?

+1  A: 

In your returned instances, if the column's name is city_name, you should be using user.city_name. Alternatively, if you use :include, you would be telling ActiveRecord to load the associated city models, which you would then reference as user.city.name.

To summarize:

users = User.find(:all, :joins => :cities, :select => "users.name, users.username, users.age, users.city_id, cities.name as city_name")
users.map(&:city_name)

users = User.find(:all, :include => :cities)
users.map(&:city).map(&:name)
François Beausoleil
+1  A: 

If you alias the joined column name then returned object should have an attribute by the alias name, i.e.

u = User.first( :joins => :cities, 
      :select => "users.*, cities.name AS city_name")
u.city_name # returns the city_name.

In your case, :joins is appropriate than :include.

I checked this in my setup and it works for me ( I am on Rails 2.3.8)

KandadaBoggu
A: 

you can use specific column name in user table in place of "users.*" if you dont need all column. I think its good programming practice.

u = User.first( :joins => :cities, :select => "users.name, users.username, users.age, users.city_id, cities.name AS city_name")

u.city_name # returns the city_name.

Mayank Jaimini