简体   繁体   中英

rails 4 scope through multiple has_one associations

I am trying to get an activerecord association through 2 layers of has_one associations and cannot quite figure it out.

I have 3 models:

class Dialog < ActiveRecord::Base
  belongs_to :contact
end

class Contact < ActiveRecord::Base
  has_many :dialogs
  belongs_to :location
end

class Location < ActiveRecord::Base
  has_many :contacts
end

I would like to create a scope in the Dialog model that allows me to pass in the id of a Location and get all Dialogs created by Contacts from the given Location... something like:

Dialog.from_location(Location.first.id)

I can get a non-activerecord array of the desired result using select:

Dialog.all.select{|s| s.contact.location_id == Location.first.id }

But I need this to return an activerecord array so that other scopes or class methods can be called on the result. I have tried using joins and includes, but am confused after reading the rails guides on how to use them.

Can anyone help me figure out how to construct a scope or class method that will accomplish this?

Thanks in advance

Just adding a note to the answer you accepted, quoting from the ruby on rails guides website:

Using a class method is the preferred way to accept arguments for scopes. These methods will still be accessible on the association objects ( link )

So in your condition, instead of doing a scope with an argument, define a method :

class Contact < ActiveRecord::Base
  has_many :dialogs
  belongs_to :location

  def self.from_location(id)
    where(location_id: id)
  end
end

You can define your scopes as follows:

class Dialog < ActiveRecord::Base
  belongs_to :contact

  scope :from_location, -> (id) do 
    where(contact_id: Contact.from_location(id).select(:id))
  end
end

class Contact < ActiveRecord::Base
  has_many :dialogs
  belongs_to :location

  scope :from_location, ->(id) do
    where(location_id: id)
  end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM