代码之家  ›  专栏  ›  技术社区  ›  JP Silvashy Gautam Rege

有助于理解多相关联(rails)

  •  3
  • JP Silvashy Gautam Rege  · 技术社区  · 14 年前

    我知道在这方面有很多资源,但我很难把它们与我的情况联系起来,所以我希望有人能帮我弄清楚这是怎么回事:

    Action ,(每当用户做了影响另一个用户的事情,比如评论他们的文章或投票给别人的照片时,就会创建这些操作),这些操作将在用户仪表板页面中列出,作为与他们相关的所有已发生的操作,如流。。。有点像Github的“新闻提要”

    Github's "News Feed"

    我决定创建一个多态关联,下面是我的模型:

    class Action < ActiveRecord::Base
      belongs_to :instigator, :polymorphic => true
      belongs_to :victim, :polymorphic => true
    end
    

    我使用了煽动者和受害者,因为任何人都可以创建这些动作,而这些动作又总是影响到另一个用户,下面是我的 User

    class User < ActiveRecord::Base
      has_many :actions, :as => :instigator
      has_many :actions, :as => :victim
    end
    

    这就是 我想 我错了,因为最终我想要一个查询,当我运行类似 User.find(1).actions instigator victim ,我想我不能同时拥有这两个 have_many ,因为这样使用时,我只得到用户是 .

    以下是我的迁移:

    create_table :actions do |t|
      t.references :instigator, :polymorphic => true
      t.references :victim, :polymorphic => true
      t.string :action_performed
      t.references :resource, :polymorphic => true
      t.timestamps
    end
    

    2 回复  |  直到 14 年前
        1
  •  2
  •   Harish Shetty    14 年前

    Rails版本无关解决方案:

    class User < ActiveRecord::Base
      has_many :instigator_actions, :class_name => "Action", :as => :instigator
      has_many :victim_actions, :class_name => "Action", :as => :victim
      has_many :actions, :finder_sql => '
           SELECT a.* 
           FROM   actions a
           WHERE  (a.instigator_type = "User" AND instigator_id = #{id}) OR 
                  (a.victim_type     = "User" AND victim_id     = #{id})'
    end
    

    在创建动作时,使用前两个关联中的一个来创建它们。

    u1.instigator_actions.create(:victim => u2)
    

    或者

    u1.victim_actions.create(:instigator => u2)
    

    actions 联想。

    u1.actions
    
        2
  •  1
  •   Shreyas    14 年前

    首先,我建议您通过单表继承来使用角色。在用户表中,可以有一个type列,用于将某人标识为煽动者或受害者。(当然,如果有人两者都是,他将有2行,所以您必须确保您没有将名称作为主键。)

    所以现在你有了一个更结构化的布局。谈到多态性问题,请尝试使用不同的接口。就像在,

    class Action < ActiveRecord::Base
      belongs_to :actionable, :polymorphic => true
    end
    

    actionable不需要是一个单独的类。这只是给接口,比如智者在协会的另一边。