2016-05-27 3 views
0

私はこのコードを使用して、現在のユーザーのためのすべての通知を取得したい:私はこの種のロジックはモデルクラスの場所でなければなりません知っているしかし1つのモデルクラスからいくつかのモデルを参照する - 悪い練習ですか?

current_user.follows.each do |follow| 
    follow.followable.open_notifications.each do |notification| 
     if !notification.reads.include?(current_user) 
      @open_notifications += notification 
     end 
    end 
end 

これまでのところ、私は私のコントローラで、このコードを持っていました。コードを移動した後 :

OpenNotificationコントローラー:

OpenNotification.fetch_unread(current_user) 

OpenNotificationモデル:

def self.fetch_unread(user) 
    @open_notifications = [] 
    user.follows.each do |follow| 
     follow.followable.open_notifications.each do |notification| 
      if !notification.reads.include?(user) 
       @open_notifications += notification 
      end 
     end 
    end 
    @open_notifications 
end 

EDIT:関与

クラス:

  • ユーザー
  • フォロー - (ユーザーが)以下のものを(追従可能)
  • 追従可能(多型 - ユーザー、イベントや場所かもしれない) - 追従可能オブジェクトの変更に関する情報が格納され
  • OpenNotificationは、
  • 読む - どの通知(USER_IDとopen_notification_idを)読ん

ユーザー:

has_many :follows, class_name: 'Follow', 
       source: :user 

has_many :follows_as_fallowable, 
       class_name: 'Follow', 
       as: :followable 

has_many :followers, through: :follows_as_fallowable, 
        source: :user 

イベント:

has_many :follows, as: :followable 
has_many :followers, through: :follows, 
         source: :user 

has_many :open_notifications, as: :followable 

OpenNotification:

belongs_to :followable, polymorphic: true 
has_many :reads 

読み込み:

belongs_to :user 
belongs_to :open_notification 

私の質問は、1つの特定のリソースを担当するクラスから複数のクラスを参照することをお勧めしますか?
これは良い習慣ではない場合、どのようにコードをリファクタリングする必要がありますか?

+0

私は別のクラスの使用については心配していません(私には、2つのクラス(「User」と何らかの「Follower」)があるように見えます。しかし、ネストされた 'each'ループは、データベースへの多くのクエリ(N + 1の問題)を引き起こすため、パフォーマンスが悪くなります。私はそれを最適化することに焦点を当てます。データベースのスキーマやモデルの関連付けを知らなくても、助言を与えるのは難しいです。あなたはクラスがどのようにつながっているのか教えてください。 – spickermann

+0

関係はかなり複雑です、私は情報(編集を参照してください)と簡単な説明を追加しました。 – Mathew

答えて

0

1つのモデル内からいくつかのモデルを参照することは、あなたの通知モデルがユーザーモデルを認識すべきであると言うことができれば完璧です(基本的に通知相互作用の大半はユーザーを処理しますか?あなたがここに示す小さなものでは、この質問のアプリケーションを幅広く考え直して評価しなければならないと言います。それが少し長めかもしれないと思うなら、誰かがこれとあなたと協力していたら(サービスオブジェクトと思う)、コードをより保守しやすく予測可能にするために、このロジックを別のクラスにエキスパートすることをお勧めします。また、@open_notificationsに通知を追加する場合は、毎回@open_notificationsオブジェクトを再構築するのではないので、<<を使用することを検討する必要があります。一方、+=は、繰り返しインスタンス化してガベージコレクタを追加します。大規模な運用では、ここで大きなスピードが得られます。

関連する問題