0

I am new in RoR 3 and I am experiencing a problem. I have a class User like this

class User < ActiveRecord::Base
  attr_accessible :firstname, :lastname, :login, :password, :rank, :sa_id, 
  belongs_to :role
  belongs_to :company
end

When in my controller I get first user (for example) User.first I can access to User.first.role

Is it possible to fetch all users including the belongs_to objects ? Like the result would be all the users and in each user an object of type role and an object of type company?

Thanks

Waseem
  • 8,232
  • 9
  • 43
  • 54
Olivier
  • 3,121
  • 2
  • 20
  • 28

2 Answers2

3

I'm not sure if this is what you're looking for but you can eager load the associations so only 1 request is sent to the database (actually 3, one for the users, one for the roles, and one for the companies)

>> users = User.includes(:role, :company)
>> users.each do |user|
     puts user.role
     puts user.company
   end

UPDATE: to render json, use

respond_with(@user) do |format|
  format.json { render json: @user.to_json(methods: [:company, :role] }
end
jvnill
  • 29,479
  • 4
  • 83
  • 86
  • Not so sure that .includes was necessary. is it ? – C404 Feb 28 '13 at 12:36
  • 2
    it is if you want to eager load. if you don't do that, you'll have to query the database each time you access `user.role` and `user.company` – jvnill Feb 28 '13 at 12:38
  • Thanks but this doesn't make any change in the returned result. I still only have my users. User.includes(:role, :company) returns only the users list and the loop doesn't change anything. – Olivier Feb 28 '13 at 12:47
  • so it appears I really didn't get your question. It would help if you show some sort of results that you are expecting. – jvnill Feb 28 '13 at 12:49
  • I expect somthing like [{ "user": { "company_id": 1, "login": "mylogin", "password": "mypassword", "role_id": 1, }, "company": { "id": 1, "name": "QuimeO", }, "role": { "id": 1, "name": "This is my role", } }, { "user": { "company_id": 1, "login": "mylogin", "password": "mypassword", "role_id": 1, }, "company": { "id": 1, "name": "QuimeO", }, "role": { "id": 1, "name": "This is my role", } }] – Olivier Feb 28 '13 at 13:00
  • so are you expecting a hash or json? – jvnill Feb 28 '13 at 13:01
  • I am expecting a json (I use repond_to :json and use respond_with user after the query – Olivier Feb 28 '13 at 13:05
  • ok just a reminder that you should've mentioned that in your question. updated my answer. – jvnill Feb 28 '13 at 13:15
  • Sorry, I thought the problem was the query, not the rendering. Thanks it works now :) – Olivier Feb 28 '13 at 13:29
0

If you used scaffolding, there should be also a generated index method inside you UsersController.

There you should see something like this:

@users = User.all

This fetches all User objects from database.

Now you can iterate over those Users and access the role field like you did before.

But: This uses lazy loading. Means: For every accessed role it will execute a separate query. To fix this use "eager loading" (http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations):

@users = User.includes(:role)

This will fetch all Users with it's associated role in one query

Benjamin M
  • 23,599
  • 32
  • 121
  • 201
  • Unfortunatly this does not seem to work. I My index is users = User.includes(:role) users.each do |user| puts user.role end respond_with users I am using respond_to :json (it that matters). – Olivier Feb 28 '13 at 13:04
  • 1
    Okay, your question is about `render json` and not about the query itself. For including things within the json output, things are almost the same: Use `include`. Look here for an example: http://stackoverflow.com/a/612475/1321564 – Benjamin M Feb 28 '13 at 13:12