【问题标题】:Rails: Using custom column to look up for has_many associationRails:使用自定义列查找 has_many 关联
【发布时间】:2013-04-03 09:33:48
【问题描述】:

我有 3 个模型:用户、列表、关注

我正在尝试实现一个系统,其中

  • 用户可以创建多个列表(列表包含照片,但与本题无关)
  • 用户可以关注其他用户创建的列表

这是我尝试构建此系统的方式:

首先我们有一个列表的数据库表:

lists: id, user_id

并指定如下模型:

class User < ActiveRecord::Base
  has_many :lists
end
class List < ActiveRecord::Base
  belongs_to :user
end

我们可以做User.first.lists 没有问题。

现在我的挑战来自尝试创建追随者。我希望用户能够找到

  1. 他关注的所有列表
  2. 他创建的所有被关注的列表
  3. 关注他的列表的所有用户(或等同于所有“关注者”)

这是我试图用来实现上述功能的数据库表:

followings: user_id, list_id, list_user_id

在此表定义中,user_id 指定谁在关注列表,list_id 指定被关注列表,list_user_id 指定被关注列表的所有者。这里使用list_user_id 来加快数据库查找速度,这样我们就不必将lists 表与users 表连接起来。

现在我被困住了。我尝试将用户模型更改为以下内容:

class User < ActiveRecord::Base
  has_many :lists
  has_many :followings

  # Works
  has_many :following_lists, :through => :followings, :class_name => "List", :source => :list

  # Doesn't work
  has_many :followed_lists, :through => :followings, :class_name => "List", :source => :list, :conditions => {:list_user_id => self.id}

  # Doesn't work
  has_many :followers, :through => :followings, :class_name => "User", :source => :user
end

第一个目标“查找他关注的所有列表”通过has_many :following_lists 毫无问题地完成。但是,似乎很难获得用户的“所有列表被关注”和“所有关注者”。

问题是似乎没有办法在followings 表中指定用于查找的键。例如,在查找用户 A 的关注者时,我需要找到 followings 表中 list_user_id 等于 A.id 的所有行,但 has_many 方法没有提供执行此操作的选项,也没有条件:conditions =&gt; {:list_user_id =&gt; self.id} 工作(它会抱怨undefined method 'id')。

那么..您将如何处理这种情况?有没有更好的方法来设计表格,或者我们可以根据当前的表格定义实际计算出一些东西?

顺便说一句,Following 模型的定义如下:

class Following < ActiveRecord::Base
  attr_accessible :list_id, :list_user_id, :user_id
  belongs_to :user
  belongs_to :list
  belongs_to :list_user, :class_name => "User"
end

【问题讨论】:

    标签: ruby-on-rails activerecord has-many


    【解决方案1】:

    您正在尝试获得以下两件事:

    1.) 他创建的所有列表

    2.) 关注他的列表的所有用户(或等效地,所有“关注者”)

    这两者都在用户拥有的列表之上进行过滤。因此与 :through => 以下的关联是不正确的。由于这会将列表范围限定为您关注的列表,而不是您拥有的列表。

    实现你想要的一种方法是这样的:

    def followed_lists
      # This essentially limits your owned lists to ones with an entry in the followings table
      lists.join(:followings).all
    end
    
    def users_following_owned_lists
      lists.followers.all
    end
    

    您需要将关注者关联添加到列表 AR。

    class List < ActiveRecord::Base
      has_many :followings
    
      has_many :followers, :through => :followings, :class_name => "User", :source => :user
    end
    

    另请注意,下表中的 list_user_id 并不是真正需要的。

    【讨论】:

    • 谢谢卡尔!第一个 - followed_lists - 按预期工作,返回所有后续列表。但是尝试第二个lists.followers.all,它抱怨NoMethodError: undefined method 'followers' for #&lt;ActiveRecord::Relation:0x007fa041c068e8&gt;。我确实将has_many :followers, ... 线放入List 模型中,我确实可以毫无问题地做list.followers。可能是因为在使用复数形式lists时,rails无法像单数形式那样关联SQL?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-06
    • 1970-01-01
    相关资源
    最近更新 更多