【问题标题】:Database model for favoriting items.收藏项目的数据库模型。
【发布时间】:2012-04-29 23:54:51
【问题描述】:

我有一个包含用户、建议和搜索的 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

现在,我正在尝试让用户收藏他们所属的搜索中的建议。障碍是用户可以喜欢队友提出的建议以及他们自己提出的建议。这意味着无法通过Suggestion 上的简单favorite 属性来完成收藏。

我试图让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

我能想到的解决这个问题的唯一方法是向Favorite 添加一个search_id 属性。但是,这会使我的收藏夹表反规范化,因为收藏夹属于属于搜索的建议,而收藏夹也直接属于搜索。

我能想到的唯一其他想法(我还没有尝试实现这一点,我无法想象它会引导我到哪里去)是用户最喜欢的关联应该通过User 和 Search 之间的连接模型,而不是分别在 User 和 Search 模型上(因为这会使表格反规范化)。

构建这个的最佳方法是什么?

对于这个问题的冗长性质,我深表歉意。

【问题讨论】:

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


    【解决方案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 查询,并且您的关联保持规范化。

    【讨论】:

    • 啊,我误解了你的问题。已编辑和修复。
    • 编辑#2:您实际上并不需要为此进行关联扩展。从 Rails 3 和 Arel 开始,您可以在关联之后链接范围。
    • 非常好。这是我正在寻找的解决方案。谢谢。
    猜你喜欢
    • 2021-03-14
    • 2018-01-17
    • 1970-01-01
    • 2013-06-21
    • 2011-09-07
    • 2012-10-15
    • 1970-01-01
    • 2011-08-11
    • 2020-03-04
    相关资源
    最近更新 更多