【问题标题】:Rails - Three models joined by a fourth. And Multiple through: associations for same modelsRails - 三个模型加上第四个模型。 And Multiple through:相同模型的关联
【发布时间】:2014-01-09 20:54:39
【问题描述】:

所以我的应用程序允许用户猜测角色的性格类型。得票最多的性格类型成为角色的性格类型,并且可以根据票数无限变化。

所以有四个模型。 用户 特点 性格 声明

(声明是连接表及其模型、控制器和视图)。

用户可以为角色投票选择个性,每个角色最多可以为每个用户的个性投票。

性格表的数据永远不会改变。

所以你看,涉及到 4 个模型,其中 3 个通过 1 连接。

这就是我所拥有的,省略了验证。

字符.rb

class Character < ActiveRecord::Base
has_many :declarations
has_many :users, through: :declarations

has_one :personality, through: :declarations # This line is in question below!
end

用户.rb

class User < ActiveRecord::Base
has_many :declarations
has_many :characters, through: :declarations

end

个性.rb

class Personality
has_many :declarations
end

声明.rb

class Declaration < ActiveRecord::Base
belongs_to :users, counter_cache: true
belongs_to :characters, counter_cache: true
belongs_to :personalities, counter_cache: true

validates :user, :character, :personality, presence: true
validates_uniqueness_of :user, :scope => [:character, :personality]
end

我想知道以下两个代码中的哪一个对于正确设置数据库关联是有效的,为什么。之后我会进入我的目的和设计。

1) 字符.rb

has_many :declarations
has_many :users, through: :declarations
has_one :personality

2) 字符.rb

has_many :declarations
has_many :users, through: :declarations
has_one :personality, through: :declarations

另外!如果我有一个 cmets 模型,其中用户通过 cmets 有很多角色,而角色通过 cmets 有很多用户,我可以添加吗?

用户和角色已经通过声明加入。通过第二个“通过:”关联再次加入他们是否有效?

【问题讨论】:

  • 感谢您的编辑

标签: sql ruby-on-rails associations


【解决方案1】:

has_one :personality, through: :declarations 将不起作用。由于每个声明可能有不同的personality,Rails 不可能决定返回什么作为 the personality。因此,has_one :trough 只能通过另一个 has_onebelongs_to 关联起作用。

由于给定角色的个性可以完全从投票中得出,因此一种合适的方法可能是将其定义为计算属性(即方法)而不是存储属性:

class Character < ActiveRecord::Base
  has_many :declarations

  def personality
    votes_by_personality = declarations.group_by(&:personality).values
    votes_by_personality.max_by(&:size).first
    # You might want to do something different than `first` if multiple
    # personalities have the same number of votes.
  end
end

这种方法的优点是personality 返回的值总是反映当前的声明。如果由于额外的查询而导致性能成为问题,您可以稍后将personality_id 列添加到字符表中,并在进行新投票时对其进行更新;但是,这需要额外的代码来保持投票和个性值同步。

顺便说一句,如果您从未将 has_many :declarations 用作该模型的属性,则在 PersonalityUser 中不需要它。 (我想你不需要查询为一个个性所做的所有投票,无论角色如何。)虽然你最常看到一对多关联的 has_many/belongs_to 对,belongs_to 在其自己的就好了。

【讨论】:

  • 好东西。非常感谢你。个性(至少在我的应用程序中)还有其他几个取决于个性键的非关键信息。给定的个性具有同样不变的 X Y 和 Z。人格 1 有 X1 Y1 Z1。人格 2 有 X2 Y2 Z2。当我在其他模型中使用它们时,我想避免重新定义所有这些方法和属性。例如,我希望用户能够声明他或自己的个性所以也许最好有一个个性模块来混合?如果是这样,Declaration 如何与该模块对话以提取 Personality 的其他信息?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多