简体   繁体   中英

Rails association scope for “more than one associated object”

Given two associated models

class Employee < ActiveRecord::Base
  belongs_to :company
end

class Company < ActiveRecord::Base
  has_many :employees
end

How would I make a scope on "Company" so it would return any company that had more than one employee?

Rails 3, DB is postgres.

Thanks in advance

You could either add a query method like so:

class Company < ActiveRecord::Base
  has_many :employees

  def self.with_employees(cnt = 1)
    select('companies.*, count(employees.id) as employee_count')
      .joins(:employees)
      .group('companies.id')
      .having('count(employees.id) > ?', cnt)
  end
end

This would enable you to call the method like so: Customer.with_employees(2) and make the count you're comparing against dynamic (eg companies w/ more that 2 employees instead of 1).

Or, look at adding a counter_cache column which would then have your Employee class look like so:

class Employee < ActiveRecord::Base
  belongs_to :company, counter_cache: true

end

The counter_cache would require an additional column on the companies table called, employees_count , and would increment/decrement every time an employee is added/deleted.

The counter_cache method would decrease the SQL query impact and make it easier to query, but can be an issue maintaining it if you're adding records directly (ie not through the Rails app).

See this for documentation on the ActiveRecord query using 'having': http://guides.rubyonrails.org/active_record_querying.html#having

And this for detail on adding a counter_cache: http://guides.rubyonrails.org/association_basics.html

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