Как отсортировать родительский класс на основе атрибута дочернего класса? - PullRequest
1 голос
/ 05 апреля 2011

У меня есть то, что мне показалось простым требованием: я хочу отсортировать родительский класс по атрибуту его дочернего класса.

class owner
  has_many :tasks
end

class task
  belongs_to :owner
end

Теперь я хочу отсортировать владельцев по дате выполнениядля их задач, так что владелец, у которого есть задача с «ближайшей» датой исполнения, является первым, и т. д.

Я могу сделать это в Ruby с сортировкой массива, но мои наборы записей огромны, и мне нужно сделатьэто с AR / СУБД ..

ОБНОВЛЕНИЕ:
Пока я размышлял над этим вопросом, часть решения пришла мне в голову, хотя я не знаю, как реализовать в AR.

Чтобы отсортировать владельцев по их задачам, релевантна только одна задача (для каждого владельца), а именно та, которая имеет ближайший срок выполнения.

Как бы я использовал AR, чтобы получить все мои данныевладельцы, отсортированные по их заданию с ближайшей датой оплаты?

ОБНОВЛЕНИЕ 2:

Task.order("due_date DESC").maximum("due_date", :group => 'owner')

Фактически передадут мне объекты владельца, отсортированные в правильном порядкекак часть заказанного хэша ([owner] => "due_date").Ура!Единственная проблема сейчас заключается в том, как мне сказать AR, чтобы eager_load все связанные задачи с объектом владельца.Потому что в этот момент каждый раз, когда я вызываю запрос

owner.tasks.each do |t|

, он запускает запрос.

Любая помощь приветствуется, я схожу с ума от этой (простой ??) проблемы,
Эрвин

Ответы [ 2 ]

2 голосов
/ 05 апреля 2011

Хорошо, так что, в конце концов, я понял это сам.

Owner.includes(:tasks).joins(:tasks).order("tasks.due_date").group(:id)

отсортирует Владельцев по ближайшему сроку выполнения их задач и будет загружать все задачи, в результате чего получится один запрос.

Обновление : добавлен сгенерированный SQL в ответ на комментарий Младена ниже.

SELECT `owners`.* FROM `owners` 
INNER JOIN `tasks` ON `tasks`.`owner_id` = `owner`.`id` 
GROUP BY owner.id ORDER BY tasks.due_date DESC

Приветствия.

0 голосов
/ 11 сентября 2016

Нашел это возможно только по чистому запросу:

Owner.find_by_sql('SELECT `owners`.*,
                           (SELECT `tasks`.`due_date`
                            FROM `tasks`
                            WHERE `owners`.`id` = `tasks`.`owner_id`
                            ORDER BY `tasks`.`due_date` DESC LIMIT 1) AS `last_due_date`
                   FROM `owners`
                   GROUP BY `owners`.`id`
                   ORDER BY `last_due_date` DESC;')

Если нужен доступ к last_due_date, добавьте к Owner модель:

def last_due_date
  if attributes['last_due_date']
    attributes['last_due_date']
  else
    tasks.order(due_date: :desc).limit(1).first.due_date if tasks.length > 0
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...