Рельсы: условно погрузочные объединения - PullRequest
2 голосов
/ 08 августа 2010

У меня есть модели club и course, где курс принадлежит клубу, а в клубе много курсов.

Когда я загружаю клуб, я также хочу загрузить связанные с ним курсы, ноЯ хочу загрузить только те из них, которые соответствуют условному тесту (approved? == true).

Как это сделать просто, если я работаю непосредственно с курсами:

@courses = Course.find( :all, :conditions => {:approved => true } )

Но яЯ хотел бы сделать это как часть заявления:

@club = Club.find(params[:id])

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

Спасибо!

Ответы [ 3 ]

2 голосов
/ 08 августа 2010

Если вы рассматриваете курс клуба только в том случае, если он был одобрен, вы можете сделать

class Club < ActiveRecord::Base
  has_many :courses, :conditions => {:approved => true}
end

и в вашем контроллере

@club = Club.find(params[:id], :include => :courses)

Теперь, я не знаю, правильно ли я вас понял, но вы сказали, что "ваши взгляды построены именно так". Вы имеете в виду своих контролеров? Потому что, если у вас есть такая логика в ваших взглядах ... DHH убивает котенка каждый раз, когда кто-то делает это.

1 голос
/ 08 августа 2010

Вы можете использовать default_scope для этого:

class Club < ActiveRecord::Base
  has_many :courses, conditions => {:approved => true}
  default_scope :include => :courses
end

class Course < ActiveRecord::Base
  default_scope :conditions => {:approved => true}
end

Теперь вы можете сделать это:

@club = Club.find(1) # this will eager load approved courses.

Ссылка:

Статья о default_scope.

Примечание 1

Я изменил ассоциацию courses в классе Club, чтобы выбрать утвержденные курсы.Теоретически это не требуется, поскольку класс Course имеет область действия по умолчанию.Но, похоже, область по умолчанию не применяется для загруженных запросов.

Примечание 2

Лично я бы не стал загружать Course объекты через default_scope.Выполнение этого через default_scope дает вам ненавязчивое решение по вашему желанию.

Я бы добавил предложение include к вызову find, чтобы загружать объекты Course только тогда, когда это необходимо.

Примечание 3

@ Райан Бигг:

Райан Бейтс рассказывает о стандартных областях видимости на полпути этого своего экрана .Он приводит пример использования областей по умолчанию для исключения удаленных записей, т. Е.

default_scope :conditions => "delete_at IS NULL"

. Я считаю, что этот вариант использования аналогичен.Как я понимаю, основные операции над моделью курса выполняются на утвержденных записях, и default_scope с опцией conditions обеспечивает это.Чтобы переопределить область по умолчанию, пользователь может использовать метод with_exclusive_scope.

Club.with_exclusive_scope{find(1)}
0 голосов
/ 09 августа 2010

Окончательное решение пришло из комбинации ответов, но ни одно из них не дошло до конца.

Текущее решение: Я использую пару именованных областей в модели course для достижения желаемой функциональности, сохраняя при этом свои представления как можно более универсальными (необходимость высушивать код является обязательным).

Итак, модель course выглядит примерно так:

class Course < ActiveRecord::Base
  belongs_to :club

  named_scope :have_approval, :conditions => { :approved => true }
  named_scope :need_approval, :conditions => { :approved => false }
end

И собрать все утвержденные курсы так же просто, как:

@approved_courses = Course.have_approval

Или при работе с club получить утвержденные курсы в клубе так же просто, как:

@club = Club.find(:first)
@approved_courses_in_club = @club.courses.have_approval

Именованная сфера - это человек!

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