Лучший способ переопределить named_scope для ассоциаций has_many в Rails? - PullRequest
0 голосов
/ 16 сентября 2010

Примечание: я использую Rails 2.3.8, а не 3.

У меня есть фотомодель с default_scope:

default_scope :conditions => ["published = ?", true], :order => :position

При вызове photo_album.photos возвращаются все опубликованные фотографии, заказанныепо положению, как и должно быть.Однако при циклическом просмотре этих фотоальбомов в административной панели для отображения количества фотографий в каждой из них получаются неправильные результаты:

pluralize(photo_album.photos.count, "photo")

возвращает 0, поскольку ни один из них не опубликован.

IЗнайте, что подобные вопросы были заданы, и ответ, как правило, выглядит так: «используйте метод класса with_exclusive_scope».Насколько я могу сказать, это полностью предотвращает использование стандартных ассоциаций Rails - в основном это приводит к чему-то вроде этого:

pluralize(Photo.all_photos_in_album(photo_album.id).count, "photo")

и требует метод класса, такой как:

def Photo.all_photos_in_album(album_id)
  self.with_exclusive_scope { find(:all, :conditions => ["photo_album_id = ?", album_id]) }
end

простодля отображения общего количества фотографий в альбоме.Это кажется безумным - переопределение значения по умолчанию не должно требовать отказа от соглашений об ассоциации Rails.with_exclusive_scope также нельзя использовать в методе экземпляра (защищенный метод) - это позволило бы мне создать метод экземпляра PhotoAlbum под названием "all_photos", чтобы хотя бы сохранить видимость ассоциаций (photo_album.all_photos).Но нет, это недопустимо: (*

Помимо удаления default_scopes, которые оказались очень полезными для всего сайта, кто-нибудь знает способ переопределения областей по умолчанию и поддержания синтаксиса ассоциации Rails?

Спасибо!

Edit:

Я закончил, добавив метод экземпляра PhotoAlbum, который, хотя это и не фактическое переопределение default_scope, делает в make более приятный синтаксис вмои взгляды:

def all_photos_count
  PhotoAlbum.count_by_sql("SELECT COUNT(id) FROM photos WHERE photo_album_id = #{self.id} ORDER BY created_at")
end

pluralize(photo_album.all_photos_count, "photo")

Хотя это не совсем ассоциация AR has_many и основана на чистом SQL, это лучший компромисс, который я нашел на сегодняшний день.

Ответы [ 2 ]

0 голосов
/ 05 октября 2010

Для меня лучшее решение в этом случае состояло в том, чтобы не использовать ни условия default_scope, ни has_many, а просто придерживаться named_scopes.Два named_scopes выполнили большую часть того, что мне было нужно, чтобы сохранить свои взгляды:

named_scope :public_list, :conditions => ["published = ?", true], :order => :position
named_scope :private_list, :order => "created_at DESC"
0 голосов
/ 16 сентября 2010

Я не понимаю, почему вы не делаете в альбоме:

has_many :photos
has_many :published_photos, :class_name => 'Photo', :conditions => ["published = ?", true], :order => :position

Так вы могли бы сделать:

@album.photos.count
@album.published_photos

И так далее ...

...