Rails 3 associations extra attributes with lazy loading

Hello,

How can one get the extra attributes from the association table while
using lazy loading like so:

I have a HMT (rails3) association and am using the includes method

to prepare my queries. But Im not able to get at the extra fields in
the association table this way.

Schema

create_table “consultants_projects”, :force => true do |t|
t.integer “consultant_id”
t.integer “project_id”
t.integer “pay_rate”
t.integer “bill_rate”
t.date “start_date”
t.date “end_date”
t.boolean “enabled”, :default => true
end

add_index “consultants_projects”, [“consultant_id”], :name =>
“index_consultants_projects_on_consultant_id”
add_index “consultants_projects”, [“project_id”], :name =>
“index_consultants_projects_on_project_id”

Model

class Project < ActiveRecord::Base
has_many :managers_projects
has_many :managers, :through => :managers_projects

We want all the extra fields on the consultants_projects

association
has_many :consultants_projects
has_many :consultants,
:through => :consultants_projects,
:select => ‘consultants.*, consultants.id,’+
'consultants_projects.id as consultants_projects_id, ’
+
‘consultants_projects.project_id,’ +
‘consultants_projects.pay_rate,’ +
‘consultants_projects.pay_rate,’ +
‘consultants_projects.bill_rate,’ +
‘consultants_projects.start_date,’ +
‘consultants_projects.end_date,’ +
‘consultants_projects.enabled AS
consultants_projects_enabled’

end

c = Consultant.includes(:projects)

c.first.projects

Does not include the extra fields like pay_rate, bill_rate etc that

are stored in the association table.

More observations I’ve found. The Arel includes method does not seem
to respect HMT :select joins. I’d prefer to use the “includes” lazy-
laoding way, but cannot seem to get the extra attributes to come back.

Both will return the Manager Model

ruby-1.8.7-p249 > p = Project.first.managers.first
=> #<Manager id: 1, first_name: “Edward”, last_name: “Scissorhands”,
email: nil, phone: nil, created_at: “2010-04-22 22:52:29”, updated_at:
“2010-04-22 22:52:29”>

ruby-1.8.7-p249 > p = Project.includes(:managers).first.managers.first
=> #<Manager id: 1, first_name: “Edward”, last_name: “Scissorhands”,
email: nil, phone: nil, created_at: “2010-04-22 22:52:29”, updated_at:
“2010-04-22 22:52:29”>

Notice that all the extra attributes are NOT passed

ruby-1.8.7-p249 > p =
Project.includes(:managers).first.managers.first.to_json
=> “{“created_at”:“2010-04-22T22:52:29Z”,“updated_at”:
“2010-04-22T22:52:29Z”,“id”:1,“phone”:null,“last_name”:
“Scissorhands”,“first_name”:“Edward”,“email”:null}”

Notice that all the extra attributes are passed

ruby-1.8.7-p249 > p = Project.first.managers.first.to_json
=> “{“created_at”:“2010-04-22T22:52:29Z”,“updated_at”:
“2010-04-22T22:52:29Z”,“project_id”:“1”,“primary”:“t”,
“manager_id”:“1”,“id”:1,“phone”:null,“last_name”:
“Scissorhands”,“first_name”:“Edward”,“email”:null}”

Here is the setup in my Model

has_many :managers_projects
has_many :managers, :through => :managers_projects,
:select => ‘managers.*, managers_projects.project_id,
managers_projects.manager_id, managers_projects.primary

interest topic. in console, use to_sql to represent SQL, Maybe found
more
hits.

2010/4/23 Will P. [email protected]

=> “{"created_at":"2010-04-22T22:52:29Z","updated_at":
"Scissorhands","first_name":"Edward","email":null}”

Schema

add_index “consultants_projects”, [“consultant_id”], :name =>
association
‘consultants_projects.start_date,’ +
are stored in the association table.


tommy xiao
E-mail: xiaods(AT)gmail.com

hi,Will
can you use gist to provide more code? it is examine your code.

2010/4/23 tommy xiao [email protected]

====================================

===================================
has_many :managers, :through => :managers_projects,

t.date    "start_date"

class Project < ActiveRecord::Base
+

To unsubscribe from this group, send email to
[email protected][email protected]


tommy xiao
E-mail: xiaods(AT)gmail.com

Hi,

Sure, here is the schema, and model files. Let me know what you
think. Why can’t I get the :select to work when using “.includes”.
In the console examples below, you can see the pay_rate and bill_rate
are not present in the example using .includes.

Schema

Consultant Model

Project Model

Console output using .includes does not honor :select

ruby-1.8.7-p249 >
Project.includes(:consultants).first.to_json(:include => :consultants)
=> “{"start_date":null,"name":"Widget Assembly","created_at":
"2010-04-22T22:52:29Z","updated_at":"2010-04-22T22:52:29Z",
"sales_contact_id":null,"id":1,"enabled":true,"client_id":
1,"consultants":[{"created_at":"2010-04-22T22:52:29Z",
"updated_at":"2010-04-23T02:35:58Z","recruiter_contact_id":
1,"payclass":2,"id":1,"enabled":true,"phone":"","last_name
":"Wright","first_name":"Steve","email":"[email protected]
"}],"end_date":null}”

Console output using does honor :select, but uses N + 1 queries for
all the consultants in a project

ruby-1.8.7-p249 > Project.first.to_json(:include => :consultants)
=> “{"start_date":null,"name":"Widget Assembly","created_at":
"2010-04-22T22:52:29Z","updated_at":"2010-04-22T22:52:29Z",
"sales_contact_id":null,"id":1,"enabled":true,"client_id":
1,"consultants":[{"start_date":null,"pay_rate":"40",
"created_at":"2010-04-22T22:52:29Z","updated_at":
"2010-04-23T02:35:58Z","recruiter_contact_id":1,"project_id":
"1","consultants_projects_id":"1","bill_rate":"80","payclass
":2,"id":1,"enabled":true,"consultants_projects_enabled":"t",
"phone":"","last_name":"Wright","end_date":null,"first_name
":"Steve","email":"[email protected]"}],"end_date":null}”

Any help is appreciated. Am I doing something wrong, or is this just
not supported?

-Will

I’ve fixed my issues. Should have been using joins vs includes as
there was really no joins happening with eager loading.

This’s what my think. use sql log you can see more details.

2010/4/24 Will P. [email protected]

=> "{"start_date":null,"name":"Widget Assembly","created_at":

":"Steve","email":"[email protected]"}],"end_date":null}"

2010/4/23 Will P. [email protected]

=> #<Manager id: 1, first_name: “Edward”, last_name:
updated_at:
Notice that all the extra attributes are passed
has_many :managers, :through => :managers_projects,

I have a HMT (rails3) association and am using the includes

t.integer "bill_rate"

Model

            'consultants_projects.id as

You received this message because you are subscribed to the Google

http://groups.google.com/group/rubyonrails-talk?hl=en.
You received this message because you are subscribed to the Google
You received this message because you are subscribed to the Google G.
“Ruby on Rails: Talk” group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected][email protected]
.
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.


tommy xiao
E-mail: xiaods(AT)gmail.com