RailsのHas_Many Associationのakand_scopeをオーバーライドする最良の方法は?
-
03-10-2019 - |
質問
注:3ではなくRails 2.3.8を使用しています。
default_scopeの写真モデルがあります:
default_scope :conditions => ["published = ?", true], :order => :position
Photo_album.photosを呼び出すと、公開されたすべての写真が必要に応じて注文されたすべての写真を返します。ただし、これらのフォトアルバムを管理パネルにループして、それぞれに写真の数を表示する場合、結果は間違っています。
pluralize(photo_album.photos.count, "photo")
公開されていないため、0を返します。
同様の質問が尋ねられたことを知っており、通常、返信は「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 Associationの条約を放棄する必要はありません。 with_exclusive_scopeは、インスタンスメソッド(保護された方法)でも使用できません - これにより、少なくとも関連性の象徴を保持するために「all_photos」と呼ばれるフォトアルバムインスタンスメソッドを作成することができました(photo_album.all_photos)。しかし、いや、それは許可されていません:(
サイト全体で非常に便利であることが証明されているデフォルト_Scopesを削除することは別として、デフォルトのスコープをオーバーライドし、Rails Associationの構文を維持する方法を知っている人はいますか?
ありがとう!
編集:
実際のdefault_scopeオーバーライドではありませんが、私のビューではるかに優れた構文を作成すると、Photo Aalbumインスタンスメソッドを追加しました。
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 Associationではなく、純粋なSQLに依存していますが、これまでに見つけた最高の妥協です。
解決 2
私にとって、この場合の最良の解決策は、default_scopeもhas_many条件も使用せず、named_scopesに固執することでした。 2つの名前の_scopesは、私の意見を無駄に保つために必要なもののほとんどを達成しました:
named_scope :public_list, :conditions => ["published = ?", true], :order => :position
named_scope :private_list, :order => "created_at DESC"
他のヒント
なぜあなたがアルバムでやっていないのかわかりません:
has_many :photos
has_many :published_photos, :class_name => 'Photo', :conditions => ["published = ?", true], :order => :position
この方法であなたがすることができます:
@album.photos.count
@album.published_photos
等々...