Сортировка таблицы базы данных Rails по столбцу в связанной модели - PullRequest
4 голосов
/ 12 января 2011

Я пытаюсь реализовать код сортируемых столбцов таблицы Райана Бейтса (Railscast # 228), но я хотел бы иметь возможность сортировки по связанному столбцу.В частности, у меня есть следующие модели и ассоциации:

class Project < ActiveRecord::Base
  belongs_to :program_manager, :class_name => "User"

class User < ActiveRecord::Base
  has_many :program_manager_projects, :class_name => "Project", :foreign_key => "program_manager_id"

Ассоциация между моделью проекта и моделью пользователя опосредована внешним ключом program_manager_id, который пользователь устанавливает в новых / редактируемых представлениях.с помощью раскрывающегося списка выбора коллекции.Вот часть аннотации в верхней части project.rb:

# Table name: projects
# program_manager_id :integer

Я хочу иметь возможность сортировать свой список проектов в индексном представлении по имени менеджера программы, то есть по project.program_manager.name.

В идеале, я бы мог указать: как-то упорядочить это имя, возможно, с помощью чего-то вроде этого в методе index моего ProjectsController:

@projects = Project.find(:all, :order => project.program_manager.name)

Но это, очевидно, победилоне работает (не говоря уже о том, что процедура Райана реализует это с конкретной ссылкой на имена таблиц из модели, которую нужно отсортировать.)

Я сталкивался с некоторыми пугающими подходами, которые используют named_scope, например:

named_scope :most_active, :select => "questions.*", :joins => "left join comments as comments_for_count on comments_for_count.question.id = questions.id", :group => "questions.id", :order => "count(questions.id) desc"

Но, учитывая отсутствие у меня опыта в MySQL, это довольно непонятно для меня.

Может ли кто-нибудь помочь мне обобщить приведенный выше пример named_scope для моего конкретного случая или указать мне на более простую стратегию?

Большое спасибо,

Дин

1 Ответ

4 голосов
/ 12 января 2011

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

named_scope :most_active, :select => "questions.*", :joins => "left join comments as comments_for_count on comments_for_count.question.id = questions.id", :group => "questions.id", :order => "count(questions.id) desc"

:most_active

название вашей области. Вы бы ссылались таким образом: Question.find (: all) .most_active

:select => "questions.*"

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

:joins => "left join comments as comments_for_count on comments_for_count.question.id = questions.id"

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

 :group => "questions.id"

Это необходимо для функции count () в предложении order, чтобы сообщить нам, что мы хотим, чтобы количество комментариев основывалось на вопросе. Нам не нужна функция count в нашем предложении order, поэтому нам также не нужен этот оператор группы

:order => "count(questions.id) desc"

Возвращать результаты в порядке количества комментариев, от самого высокого до самого низкого.

Так что для нашего примера, отбрасывая то, что нам не нужно, и применяя к вашим потребностям, мы получаем:

:named_scope :by_program_manager_name, :joins => "left join users on projects.program_manager_id = users.id", :order => "users.name"

Этот named_scope будет называться так:

Project.find(:all).by_program_manager_name

Обратите внимание, что это в основном эквивалентно:

Project.find(:all, :joins => "left join users on projects.program_manager_id = users.id", :order => "users.name")

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

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