On Monday, 29 September 2014 23:15:36 UTC-4, Austin York wrote:
>
> In a todo list-style app, I have the following ActiveRecord model method:
>
> class Task < ActiveRecord::Base
> # ...
> def project_name
> project.tasks.length > 0 ? "#{project.name} - #{name}" : project.name
> end
> end
>
> The idea is to provide additional project information if there are one or
> more tasks on the project.
>
> However, when invoked regularly on views this creates performance concerns
> (especially with a growing data set).
>
> What is the best way to optimize this query so that it doesn't create N+1
> query type issues when invoked from "each" loops in the view?
>
+1 what MichaĆ said about eager-loading. One additional tricky thing:
prefer `size` over `length` for associations and relations. In plain Ruby,
`size`, `length` and `count` are more or less identical - but for
ActiveRecord collections they have slightly different meanings:
* `length` is the most straightforward: it's ALWAYS the number of records
in the collection. If the collection isn't currently loaded, calling
`length` on it will trigger a SQL query to load all the records.
* `count` is the opposite: it ALWAYS runs a SQL query. It doesn't load
records, it uses SQL's `COUNT()` function. It can also return things that
aren't numbers; doing `Task.group(:project_id).count` will give you back a
hash with `project_id`s as keys and the number of matching tasks as values.
* `size` is the middle: if the collection is loaded, it works like
`length`. Otherwise it works like `count`...
--Matt Jones
--
You received this message because you are subscribed to the Google Groups "Ruby
on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/rubyonrails-talk/e6771c47-1c12-4e5a-8fe6-73af4d7b26e3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.