用于收藏项目的数据库模型。

时间:2012-04-29 23:54:51

标签: ruby-on-rails ruby ruby-on-rails-3 database-design activerecord

我有一个包含用户,建议和搜索的Rails应用程序。用户和搜索之间存在多对多关联,因此每个用户可以进行多次搜索,每次搜索都可以有多个用户(称为“搜索者”)。

用户可以为他们所属的每个搜索提出建议。因此,每个Suggestion都属于User和Search。

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成为User和Suggestion之间的连接模型。

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属性。但是,这会使我的收藏表失去正常化,因为收藏夹属于一个属于搜索的建议,而收藏夹也属于直接搜索。

我能想到的唯一另一个想法(我还没有尝试过实现这个想法,我无法想象它会引导我到哪里)是用户最喜欢的关联应该通过用户和搜索之间的连接模型,而不是单独的用户和搜索模型(因为这会使表格不规范化)。

建筑师的最佳方法是什么?

我对这个问题的冗长性质表示道歉。

1 个答案:

答案 0 :(得分: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查询,并且您的关联保持规范化。