0

ユーザー、提案、検索を備えたRailsアプリがあります。ユーザーと検索の間には多対多の関連付けがあり、各ユーザーは多くの検索に参加でき、各検索には多くのユーザー (「検索者」と呼ばれます) が含まれます。

ユーザーは、メンバーである各検索に提案を行うことができます。したがって、各提案はユーザーと検索に属します。

class Suggestion < ActiveRecord::Base
  belongs_to :suggester, class_name: 'User'
  belongs_to :search
end

class Search < ActiveRecord::Base
  # ... user-search associations.

  has_many :suggestions
end

class User < ActiveRecord::Base
  # ... user-search associations.

  has_many :suggestions, foreign_key: :suggester_id
end

現在、ユーザーがメンバーである検索で作成されるお気に入りの提案を許可しようとしています。問題は、ユーザーがチーム メイトによって作成された提案と、自分で作成した提案をお気に入りにできることです。これは、 の単純なfavorite属性を介してお気に入りを作成できないことを意味しますSuggestion

Favoriteユーザーと提案の間の結合モデルを作成しようとしました。

class Favorite < ActiveRecord::Base
  belongs_to :user
  belongs_to :suggestion
end

ただし、特定の検索内から特定のユーザーがお気に入りにした提案にアクセスするのに問題があります。例えば:

class Search < ActiveRecord::Base
  has_many :suggestions

  def suggestions_favoured_by(user)
    # here I need to grab the search's suggestions and then scope them
    # down to only these that have an entry in the favorites table which
    # has user_id == user.id.
    # That seems ridiculously complicated.
  end
end

この問題を解決する唯一の方法は、 にsearch_id属性を追加することFavoriteです。ただし、お気に入りは検索に属する提案に属し、お気に入りも検索に直接属しているため、お気に入りテーブルが非正規化されます。

私が考えることができる他の唯一のアイデア (そして、私はまだこれを実装しようとしていません。頭の中でどこにつながるのかを視覚化するのに苦労しています) は、ユーザーとお気に入りの関連付けが結合モデルを通じて発生する必要があるということです。ユーザー モデルと検索モデルを別々に使用するのではなく、ユーザー モデルと検索モデルの間で使用します (テーブルが非正規化されるため)。

これを設計する最良の方法は何ですか?

質問が長々とした性質のものであることをお詫びします。

4

1 に答える 1

1

suggestions_favoured_by手動でフィルタリングを行うメソッドを実装せずに、スコープを使用してこれを行うことができます。

class Suggestion < ActiveRecord::Base
  has_many :favorites
  scope :favoured_by, lambda { |user_id|
    joins(:favorites).
    where(:favorites => {:user_id => user_id})
  }
end

次に、特定のユーザーのお気に入りの提案にアクセスするにはsearch:

search.suggestions.favoured_by(user_id)

Rails が SQL クエリの作成を担当し、関連付けは正規化されたままになります。

于 2012-04-30T00:21:55.497 に答える