Самостоятельное соединение Rails с условием относится только к родителю - PullRequest
0 голосов
/ 14 мая 2018

Возьмите http://guides.rubyonrails.org/association_basics.html#self-joins, например,

class Employee < ApplicationRecord
  has_many :subordinates, class_name: "Employee", foreign_key: "manager_id"
  belongs_to :manager, class_name: "Employee"
end

Если я хотел бы применить к условию, говоря, только Сотрудник с is_manager (при условии, что у Employee есть такое логическое поле) true , является менеджером и может отображать подчиненных

Если я просто изменю вышеприведенное значение на следующее

class Employee < ApplicationRecord
  has_many :subordinates, -> {where is_manager: true}, class_name: "Employee", foreign_key: "manager_id"
  belongs_to :manager, class_name: "Employee"
end

Это не будет работать, поскольку условие where is_manager: true также будет применяться к subordinates.

FROM `employees` WHERE `employees`.`is_manager` = 1 AND (employees.manager_id = 1)

Но я хочу применять только к руководителю, а не к подчиненным.

Что-то вроде

Employee.where(manager_id: employee.where(is_manager: true))

Так что, если я позвоню

employee = Employee.find 1 
employee.subordinates

Сначала, он проверит, является ли сотрудник руководителем, если да, вернет подчиненных;в противном случае вернуть пустой массив

1 Ответ

0 голосов
/ 14 мая 2018

Почему бы не создать метод класса [1], as_manager. Что-то вроде:

class Employee < ApplicationRecord
  has_many :subordinates, class_name: "Employee", foreign_key: "manager_id"
  belongs_to :manager, class_name: "Employee"

  class << self

    def as_manager
      where(is_manager: true)
    end

  end
end

Тогда вы должны быть в состоянии сделать:

Employee.as_manager.subordinates

Или, учитывая ваши «бизнес-требования» (очень странно, что у бизнеса будут требования для такого уровня детализации реализации), как насчет того, чтобы просто исключить метод subordinates, предоставленный директивой has_many?

class Employee < ApplicationRecord
  has_many :subordinates, class_name: "Employee", foreign_key: "manager_id"
  belongs_to :manager, class_name: "Employee"

  def subordinates
    is_manager ? where(manager_id: id) : []
  end

end

Таким образом, вы можете сохранить все другие методы, предоставляемые has_many, но получить поведение, которое вы хотите для subordinates.

[1] Йорг Миттаг желает заявить:

Я один из тех Ruby Purists, которому нравится указывать на то, что в Ruby нет такого понятия, как метод класса. Тем не менее, я в полном порядке, используя термин метод класса в разговорной речи, , пока все стороны полностью понимают, что речь идет о разговорной речи . Другими словами, если вы знаете , что не существует такого понятия, как метод класса, и что термин «метод класса» просто сокращен от «метод экземпляра синглтон-класса объекта, который является экземпляром Class ", тогда проблем нет. Но в остальном я видел, как это мешало пониманию.

Пусть все стороны полностью поймут, что термин метод класса используется выше в разговорном смысле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...