Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

undefined method `includes' for object instance

I'm using Ruby 2.2.1 and Rails 4.2 to build an app. At one of my views, I got the following message:

N+1 Query detected Politician => [:account] Add to your finder: :includes => [:account]

N+1 Query method call stack

app/models/user.rb:19:in `account'

app/controllers/home_controller.rb:6:in `index'

Here is my action at home controller:

@account = current_user.account
@new_contacts = current_user.contacts.created_this_week.count
@new_collabs = current_user.collaborators.created_this_week.count

And the relevant section of user model:

belongs_to :role, polymorphic: true, dependent: :destroy
delegate :account, to: :role
delegate :collaborators, to: :role
delegate :contacts, to: :role

I already tried to the following:

@account = current_user.account.includes(:contacts, :collaborators)

But I only get the error:

undefined method `includes' for <Account:0x007fa7474e04a8>

I did some research and what it seems is that includes works only for relations (which is not the case).

Is bullet worrying for nothing? What can I do to this stop being a N+1 query?

Thanks!

like image 490
Igor_Marques Avatar asked Jun 05 '15 19:06

Igor_Marques


1 Answers

includes can only be called on ActiveRecord::Relations or ActiveRecord::Base children classes, account seems to be a instace of a model, thus not respond to ActiveRecord::Relation methods like includes. It seems a false positive from bullet as soon as you are only getting account from current_user, although I don't recommend delagations to associations, it can lead to N + 1 problems in the feature.


Replacing delagate with AR association:

Assuming that Account is a regular ActiveRecord model you can use has_one macro (look at documentation for more details):

has_one :account, through: :role

It's very handful when you need to iterate through users:

# You can avoid `N + 1`
User.includes(:account).limit(50).each { |u| puts u.name }
like image 98
Brenno Costa Avatar answered Nov 04 '22 10:11

Brenno Costa