简体   繁体   English

通过多个has_one关联的Rails 4作用域

[英]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. 我正在尝试通过2层has_one关联来获得activerecord关联,并且无法完全弄清楚。

I have 3 models: 我有3种型号:

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模型中创建一个范围,该范围使我可以传递Location的ID并从给定的Location获取由Contacts创建的所有Dialog ...类似于:

Dialog.from_location(Location.first.id)

I can get a non-activerecord array of the desired result using select: 我可以使用select获得所需结果的非activerecord数组:

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. 但是我需要它返回一个activerecord数组,以便可以在结果上调用其他作用域或类方法。 I have tried using joins and includes, but am confused after reading the rails guides on how to use them. 我曾尝试使用联接和包含,但在阅读了有关如何使用它们的Rails指南后感到困惑。

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: 只需在您接受的答案上添加注释,并引用Rails指南网站上的ruby:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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