これを実装するか、Single-Table-Inheritance (STI) に分割するのに助けが必要です。私はそれについて読んだことがありますが、これが正しい方法であるかどうかはまだよくわかりません. 実装するための提案があれば。もしくは、今の自分と大きく違っていても、アドバイスをお願いします。
したがって、通常、次のクラス(すべてのモデル)があります。
class Article < ActiveRecord::Base
has_many :attachments
has_many :medias
has_one :banner
accepts_nested_attributes :medias
...
end
class Attachment < ActiveRecord::Base
belongs_to :article
end
class Media < Attachment
default_scope { where(attachment_type: 'media') }
def audio?; media_type == 'audio'; end
def video?; media_type == 'video'; end
validate :embed_url, presence: true if :video?
def path
if audio?
# Different audio path
elsif video?
# Different video path
end
end
after_commit :process_audio_file
def process_audio_file; ...; end
after_commit :process_video_file
def process_video_file; ...; end
end
class Banner < Attachment
default_scope { where(attachment_type: 'banner') }
...
end
そして、通常、それも正常に機能します..
article = Article.first
first_media = article.medias.first
banner = article.banner
しかし、それMedia
はおそらく肥大化し、さまざまなメディアタイプに対してさまざまなことを行うさまざまなロジックが多すぎることに気付きました。だから私はこれを行うことによってそれらを分離しようとしました:
class Article < ActiveRecord::Base
has_many :attachments
has_many :medias
has_one :banner
accepts_nested_attributes_for :medias
end
class Attachment < ActiveRecord::Base
belongs_to :article
end
class Media < Attachment
default_scope { where(attachment_type: 'media') }
end
class AudioMedia < Media
default_scope { where(media_type: 'audio') }
def path
# Audio path
end
after_commit :process_audio_file
def process_audio_file; ...; end
end
class VideoMedia < Media
default_scope { where(media_type: 'video') }
validate :embed_url, presence: true
def path
# Video path
end
after_commit :process_video_file
def process_video_file; ...; end
end
ここで、ロジックを互いに分離しました。すごい!しかし、今では次のような問題がいくつかあります。
article = Article.first
first_media = article.medias.first
これを行うことで、私はMedia
クラスにいるだけです...AudioMedia
クラスと言うには、私がしなければならないことは次のとおりです。
"#{first_media.media_type}Media".constantize.find(first_media.id)
また、nested_attributes を機能させるには、定義する必要があります
accepts_nested_attributes_for :audio_medias
accepts_nested_attributes_for :video_medias
それを正しく機能させるには?次に、それらの関係を次のように定義する必要があります。
has_many :medias
has_many :audio_medias
has_many :video_medias
何かアドバイス?ありがとう、乾杯!
編集
関連するテーブルとフィールドを追加
articles
id
[some_other_fields]
attachments
id
article_id
attachment_type # media, banner, etc...
media_type # audio, video, etc...
[some_other_fields]