On Martes, 5 de Octubre de 2010 15:35:35 Andrey Voronkov escribió: > Now I have: > > config.columns[:last_statecustomer_name].includes = > [:customer_programs => :statecustomer] > > def last_statecustomer_name > customer_programs.last(:order => :date).statecustomer.try(:name) > end > > Same N+1:
Again you are passing find options to last method (order), so ActiveRecord must reload the association. You must remove arguments in last method. A workaround would be sort objects by date, using sort_by(&:date) and call last without arguments. > CustomerProgram Load (0.3ms) SELECT `customer_programs`.* FROM > `customer_programs` WHERE (`customer_programs`.program_id IN > (29,10,12,24,20,15,13,26,11,28,14,16,25,19,30,21,23,32,17,27,18,8,22,9,80,1 >29,1,31,130)) CustomerProgram Columns (1.4ms) SHOW FIELDS FROM > `customer_programs` Statecustomer Load (0.2ms) SELECT * FROM `customers` > WHERE > (`customers`.`id` IN (11,6,7,12,13,8,9,15,1,2,3,10,4,5)) AND ( > (`customers`.`type` = 'Statecustomer' ) ) > Rendering template within layouts/application > Rendering list > Rendered _list_header (13.1ms) > Rendered _list_column_headings (18.7ms) > Rendered _messages (2.4ms) > Rendered _list_messages (29.1ms) > CustomerProgram Load (0.2ms) SELECT * FROM `customer_programs` > WHERE (`customer_programs`.program_id = 29) ORDER BY date DESC LIMIT 1 > Statecustomer Load (0.2ms) SELECT * FROM `customers` WHERE > (`customers`.`id` = 8) AND ( (`customers`.`type` = 'Statecustomer' ) ) > Rendered _list_record_columns (33.5ms) > Rendered _list_actions (30.5ms) > Rendered _list_record (93.1ms) > CustomerProgram Load (0.3ms) SELECT * FROM `customer_programs` > WHERE (`customer_programs`.program_id = 10) ORDER BY date DESC LIMIT 1 > Statecustomer Load (0.2ms) SELECT * FROM `customers` WHERE > (`customers`.`id` = 1) AND ( (`customers`.`type` = 'Statecustomer' ) ) > Rendered _list_record_columns (25.0ms) > Rendered _list_actions (27.3ms) > Rendered _list_record (54.4ms) > CustomerProgram Load (0.2ms) SELECT * FROM `customer_programs` > WHERE (`customer_programs`.program_id = 12) ORDER BY date DESC LIMIT 1 > CACHE (0.0ms) SELECT * FROM `customers` WHERE (`customers`.`id` = > 8) AND ( (`customers`.`type` = 'Statecustomer' ) ) > > 2010/10/5 Sergio Cambra .:: entreCables S.L. ::. <[email protected]>: > > On Martes, 5 de Octubre de 2010 12:20:15 Andrey Voronkov escribió: > >> I have simple situation: > >> Program ---< CustomerProgram >--- Statecustomer > >> > >> In ProgramsController list action I want to show virtual column named > >> > >> :last_statecustomer_name. So: > >> > >> In my ProgramsController: > >> ... > >> config.columns[:last_statecustomer_name].includes = [:customer_programs] > >> ... > >> > >> In Program model: > >> ... > >> def last_statecustomer_name > >> customer_programs.last(:order => :date, :include => > >> [:statecustomer]).try(:statecustomer).try(:name) > >> end > >> > >> And I'm getting N+1: > >> Dcp Load (0.6ms) SELECT `programs`.* FROM `programs` WHERE > >> ((`programs`.`parent_id` IS NULL)) AND ( (`programs`.`type` = 'Dcp' ) > >> ) ORDER BY `programs`.`name` ASC LIMIT 0, 30 > >> CustomerProgram Load (0.3ms) SELECT `customer_programs`.* FROM > >> `customer_programs` WHERE (`customer_programs`.program_id IN > >> (29,10,12,24,20,15,13,26,11,28,14,16,25,19,30,21,23,32,17,27,18,8,22,9,8 > >>0,1 29,1,31,130)) CustomerProgram Columns (1.4ms) SHOW FIELDS FROM > >> `customer_programs` Rendering template within layouts/application > >> Rendering list > >> Rendered _list_header (42.5ms) > >> Rendered _list_column_headings (36.4ms) > >> Rendered _messages (2.7ms) > >> Rendered _list_messages (43.3ms) > >> CustomerProgram Load (0.3ms) SELECT * FROM `customer_programs` > >> WHERE (`customer_programs`.program_id = 29) ORDER BY date DESC LIMIT 1 > >> Statecustomer Columns (1.6ms) SHOW FIELDS FROM `customers` > >> Statecustomer Load (0.2ms) SELECT * FROM `customers` WHERE > >> (`customers`.`id` = 8) AND ( (`customers`.`type` = 'Statecustomer' ) ) > >> Rendered _list_record_columns (67.0ms) > >> Rendered _list_actions (103.8ms) > >> Rendered _list_record (199.3ms) > >> CustomerProgram Load (0.2ms) SELECT * FROM `customer_programs` > >> WHERE (`customer_programs`.program_id = 10) ORDER BY date DESC LIMIT 1 > >> Statecustomer Load (0.2ms) SELECT * FROM `customers` WHERE > >> (`customers`.`id` = 1) AND ( (`customers`.`type` = 'Statecustomer' ) ) > >> Rendered _list_record_columns (27.5ms) > >> Rendered _list_actions (28.3ms) > >> Rendered _list_record (58.0ms) > >> CustomerProgram Load (0.3ms) SELECT * FROM `customer_programs` > >> WHERE (`customer_programs`.program_id = 12) ORDER BY date DESC LIMIT 1 > >> CACHE (0.0ms) SELECT * FROM `customers` WHERE (`customers`.`id` = > >> 8) AND ( (`customers`.`type` = 'Statecustomer' ) ) > >> Rendered _list_record_columns (26.2ms) > >> Rendered _list_actions (27.3ms) > >> Rendered _list_record (55.7ms) > >> CustomerProgram Load (0.2ms) SELECT * FROM `customer_programs` > >> WHERE (`customer_programs`.program_id = 24) ORDER BY date DESC LIMIT 1 > >> Statecustomer Load (0.2ms) SELECT * FROM `customers` WHERE > >> (`customers`.`id` = 4) AND ( (`customers`.`type` = 'Statecustomer' ) ) > >> Rendered _list_record_columns (26.9ms) > >> Rendered _list_actions (27.8ms) > >> Rendered _list_record (56.9ms) > >> CustomerProgram Load (0.2ms) SELECT * FROM `customer_programs` > >> WHERE (`customer_programs`.program_id = 20) ORDER BY date DESC LIMIT 1 > >> Statecustomer Load (0.2ms) SELECT * FROM `customers` WHERE > >> (`customers`.`id` = 9) AND ( (`customers`.`type` = 'Statecustomer' ) ) > >> > >> > >> What am I doing wrong? > > > > Your include work becuase second query is loading associated customer > > programs in only one query, but later you are forcing to reload > > customer_programs in your virtual column: > > > > customer_programs.last(:order => :date, :include => [:statecustomer]) > > > > You are passing find options to last method (order and include), so > > ActiveRecord must reload the association. You could try to set includes > > as [:customer_programs => :statescustomer] and remove arguments in last > > method. I haven't tried to set includes with a second level include but I > > think it should work (it works at :includes option of find method). > > -- > > Sergio Cambra .:: entreCables S.L. ::. > > Mariana Pineda 23, 50.018 Zaragoza > > T) 902 021 404 F) 976 52 98 07 E) [email protected] > > > > -- > > You received this message because you are subscribed to the Google Groups > > "ActiveScaffold : Ruby on Rails plugin" group. To post to this group, > > send email to [email protected]. To unsubscribe from this > > group, send email to [email protected]. For > > more options, visit this group at > > http://groups.google.com/group/activescaffold?hl=en. -- Sergio Cambra .:: entreCables S.L. ::. Mariana Pineda 23, 50.018 Zaragoza T) 902 021 404 F) 976 52 98 07 E) [email protected] -- You received this message because you are subscribed to the Google Groups "ActiveScaffold : Ruby on Rails plugin" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/activescaffold?hl=en.
