単一テーブル継承のモデル側で表示する内容を変更する
やりたいこと
◯抽象クラスNewsを継承した、FollowStartNewsやTweetFavNewsなど具象クラスを使うことで、タイプコードを削減する。
◯News一覧を見るときに、News.all.each{|news| news.body}で、その内容が見たい。
◯なおかつnews.bodyの内容はFollowStartNewsやTweetFavNewsなどによって異なる。
もう少し詳しく説明すると、
◯news_tableだけがDBに存在し、そこにはuser_id(当事者), tweet_id(対象のツイート),target_user_id(対象のユーザ)などの参照が存在する。
◯FollowStartNews < News ・・・いわゆる単一テーブル継承。
◯FollowStartNewsのbodyは"#{self.user.name}が#{self.target_user.name}をフォローしました"
◯TweetFavNewsのbodyは"#{self.user.name}が#{self.tweet}をいいねといっています"
そもそもこのような設計にした理由は①Typeコードからポリモーフィズムへ、の実践 ②構造はやや異なるがなるべく使用するインターフェースを共通化したい、の2点。
で、実際単なる文字列を出すだけなら上の通りやればいい。しかし、実際は#{self.user.name}がuserのページへのリンクだったりするとうれしい。しかしモデルからは通常link_toなどは使えない。
かといって、Helperにその実装を委ねると@news.bodyという呼び出しがfollow_start_news_format(@news)とかになっちゃいそう(=インターフェースが統一できない)。それはダサい。。。
で、とりあえず結論。
◯app/models/follow_start_news.rb
class FollowStartNews < News include Rails.application.routes.url_helpers include ActionView::Helpers def body { "ja" => "#{link_to self.user.name, user_path(self.user)}が#{link_to self.target_user.name, user_path(self.target_user)}をフォローしました" } end end
もしモデルに表示系のロジックが入り込むのがイヤなら、これをFollowStartNewsHelperとかにぶち込んで、bodyからはそれを呼び出せばよいだろう。(そのときはたぶんinclude FollowStartNewsHelperだけで良いと思う)