0

I have two models:

class User < ActiveRecord::Base
 has_one :user_profile
end

class UserProfile < ActiveRecord::Base
  belongs_to :user
end

a User has one UserProfile, and a UserProfile belongs to a User

The tables structure:

User

id : integer name : string email : string

UserProfile

id : integer user_id : integer bio : string blog_url : string

Using rails console, I try to get the information of a User by joining both tables:

User.joins(:user_profile).includes(:user_profile).where(user_profiles: {user_id: 1})

The result on the console screen shows me only the User table, the UserProfile table doesn't show up.

 => [#<User id: 1, name: "Alan", email:"alan@example.com">]

The SQL statement that appeared on the console screen (the SELECT "users"."id" bla bla...) seems right, since when I copy and paste it to SQLite browser and execute the command, it shows me the result as I expected.

|id| name | email            | id | user_id | bio         | blog_url         | 
------------------------------------------------------------------------------
|1 | Alan | alan@example.com | 1  | 1       | lorem ipsum | alan.example.com |

So I found two different results here.

What might cause these tables not joining on my console?

Abednego
  • 367
  • 1
  • 7

1 Answers1

0

what you see in console:

=> [#<User id: 1, name: "Alan", email:"alan@example.com">]

is a string representation of a User object, default representation does not include loaded associations(imagine you had million other objects associated with that user - you wouldn't be able to get the thing rendered at all)

to access user profile from user object you have a convenient #user_profile method:

p user.user_profile

to be sure that you're actually fetching this thing from memory and not revisiting database(which is what you are using .include() for) you can tail log/development.log and see that there are no SELECT * FROM user_profiles queries at the time when you access user_profile object

also you don't need both .joins() and .includes(). usually .includes() does all you need.

keymone
  • 8,006
  • 1
  • 28
  • 33
  • Understood. So when I need to display a value from the associated object, I may have to use something like `user.user_profile.blog_url`. – Abednego Aug 07 '13 at 09:22
  • exactly. it's separate objects that have different set of attributes that are exposed via respective methods on those objects. – keymone Aug 07 '13 at 13:00