开发者

to_json :include on active record requires database

I want to produce a json string with one level of associations:

@lines = Line.joins(:mems)\
             .where("     lines.document_id = ?
                      AND lines.text <> 'root'
                      AND mems.review_after < ?", params[:id], Time.now())\
             .to_json :include => :mems

My development log is as follows:

  Line Load (0.4ms)  SELECT `lines`.* FROM `lines` INNER JOIN `mems` ON `mems`.`line_id` = `lines`.`id` WHERE ( lines.document_id = '30'
 AND lines.text <> 'root'
 AND mems.review_after < '2011-01-10 04:14:59')
  Mem Load (0.2ms)  SELECT `mems`.* FROM `mems` WHERE (`mems`.line_id = 49)
  Mem Load (0.3ms)  SELECT `mems`.* FROM `mems` WHERE (`mems`.line_id = 50)
  Mem Load (0.2ms)  SELECT `mems`.* FROM `mems` WHERE (`mems`.line_id = 51)
  Mem Load (0.3ms)  SELECT `mems`.* FROM `mems` WHERE (`mems`.line_id = 52)
  Tag Load (0.1ms)  SELECT `tags`.* FROM `tags` WHERE (`tags`.`id` = 8) LIMIT 1
Rendered documents/review.erb within layou开发者_运维知识库ts/application (11.3ms)

As you can see, the ActiveRecord object produces a single query with an inner join. However, the to_json method queries the associated model individually for each Line record.

Is there a way to avoid these duplicate queries without writing a custom serialization method?


This is because :include eager loads related objects from the database, you'll need to use it on your original query.

The solution is simple: just use includes:

@lines = Line.includes(:mems)\
         .where("lines.document_id = ?
                 AND lines.text <> 'root'
                 AND mems.review_after < ?", params[:id], Time.now())\
         .to_json :include => :mems
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜