Ruby on rails Rails:糟糕的联想?[有很多,通过]如何测试是否有效?

Ruby on rails Rails:糟糕的联想?[有很多,通过]如何测试是否有效?,ruby-on-rails,model,associations,erd,Ruby On Rails,Model,Associations,Erd,我正在努力解决数据模型中的一个问题。我有以下型号: class User < ActiveRecord::Base ... has_many :claims #user-claims has_many :claims, through: :rulings, as: :commissars ... end class Claim < ActiveRecord::Base ... belongs_to :user has_many :users, through: :

我正在努力解决数据模型中的一个问题。我有以下型号:

class User < ActiveRecord::Base
...
  has_many :claims #user-claims
  has_many :claims, through: :rulings, as: :commissars
...
end

class Claim < ActiveRecord::Base
 ...
  belongs_to :user
  has_many :users, through: :rulings, as: :commissars
 ...
end

class Ruling < ActiveRecord::Base
    belongs_to :user
    belongs_to :claim
end
class用户
错误:

undefined method `commissars' for #<Claim:0xc5ac090>
未定义的“委员”方法#
模型说明:

用户可以编写声明(声明属于一个用户),用户可以扮演委员的角色来裁决声明(每个声明的委员最大数量=3)


有没有办法解决这个问题或改善关系?

首先,我建议你回去仔细阅读,因为我相信你从根本上误解了很多事情。例如,
as:
选项并不表示角色,而是表示多态联接的存在。此外,您不能在同一型号上两次声明
有多个:索赔。不管怎样,再去读一读吧

但是,对于你的问题,一种功能性的虽然有点不雅的方法可能看起来像:

class User < ActiveRecord::Base
  ...
  has_many :claims 
  has_many :claim_commissars, foreign_key: "commissar_id"
  has_many :commissar_claims, through: :claim_commissars, class_name: "Claim" 
  #                                                     ^^^^^^^^^^^^^^^^^^^^^
  #                                                     this bit may be wrong
  ...
end

class Claim < ActiveRecord::Base
  ...
  belongs_to :user
  has_one    :ruling
  has_many   :claim_commissars
  has_many   :commissars, through: :claim_commissars
  ...
end

class ClaimCommissar < ActiveRecord::Base
  ...
  belongs_to :claim
  belongs_to :commissar, class_name: "User"
  ...
end

class Ruling < ActiveRecord::Base
  ...
  belongs_to :claim
  belongs_to :commissar, class_name: "User"
  ...
end
class用户
您需要在代码中强制执行“最多3名委员”

这是没有测试,你可能需要摆弄它,让它去。但是,希望它能让你朝着更好的方向前进


祝你好运

这个域模型需要相当复杂的som关系,所以不第一次尝试就得到它并不丢脸

让我们从用户和声明开始:

class User < ActiveRecord::Base
  has_many :claims, foreign_key: 'claimant_id',
                    inverse_of: :claimant
end

class Claim < ActiveRecord::Base
  belongs_to :claimant, class_name: 'User',
                        inverse_of: :claims
end
请注意,这里我们有一个与用户的关系,为了清楚起见,我们称之为
专员。现在,我们将关系添加到
索赔

class Claim < ActiveRecord::Base
  belongs_to :claimant, class_name: 'User',
                        inverse_of: :claims
  has_many :rulings
  has_many :commissioners, through: :rulings
end
每项索赔的最大委员人数=3人

这实际上不是关联的一部分,而是通过添加验证或关联回调来强制执行此规则

class Ruling < ActiveRecord::Base

  # ...

  validate :only_three_rulings_per_claim

  private 

    def only_three_rulings_per_claim
      if claim.rulings.size >= 3
        errors.add(:claim, "already has the max number of commissars")
      end
    end
end

类规则=3
错误。添加(:声明“已拥有最大数量的委员”)
结束
结束
结束
见:


请显示
裁决
模型。
类别裁决
@jvillian好了,更新了第一条评论,感谢我们使用
claim.rulings.size>=3
而不是
claim.rulings.size==3
,因为由于比赛条件的原因,完全有可能有超过3个的人偷偷通过!很好的解决方案,马克斯。我不认识你,但我总是从你的答案中学到很多。谢谢你为我们提供了一个很好的地方。另外,感谢你为我们提供了迁移的机会。这是一个非常好的添加,非常有帮助(依我看)。谢谢你!我需要放轻松,理解你写下的一切。但你为此付出了多少努力,这一点很突出。:)+100个喜欢:这是一个很好的尝试,但是不需要
ClaimCommissar
表,因为
裁决
已经充当了用户和索赔之间的m2m连接表。我同意这一点。我想我当时在想(对该领域一无所知),使用
裁决
作为加入模型似乎很奇怪,因为裁决(这是我的假设-可能是错误的)发生在
声明
用户
(作为作者)以及一个或多个
用户
作为委员关联之后。因此,新模式的引入。但是,这都是基于对领域的一个假设。而且,我个人会完全不同,使用更合适的角色和关系——但这是因为我建立了一个库,可以无缝地完成这一切。考虑到OP车型的现状,我觉得“功能性但有点不雅”的解决方案是合适的。然而,您的解决方案非常优秀,在许多方面,我们的两个解决方案是方向一致的。我希望OP会发现这些有帮助。当然!我仍在努力,以充分理解(rails上的新功能)和我支持的第一个完整项目,因此需要时间以任何方式处理。我非常感谢您的巨大努力,当然它将解决问题。:)
class User < ActiveRecord::Base
  has_many :claims, foreign_key: 'claimant_id',
                    inverse_of: :claimant

  # rulings as claimant
  has_many :rulings, through: :claims

  has_many :rulings_as_commissioner, class_name: 'Ruling',
                                     foreign_key: 'commissioner_id'
  has_many :claims_as_commissioner, through: :rulings_as_commissioner,
                                    source: :claim
end
class CreateClaims < ActiveRecord::Migration
  def change
    create_table :claims do |t|
      t.belongs_to :claimant, index: true, foreign_key: false
      t.timestamps null: false
    end
    # we need to setup the fkey ourself since it is not conventional
    add_foreign_key :claims, :users, column: :claimant_id
  end
end

class CreateRulings < ActiveRecord::Migration
  def change
    create_table :rulings do |t|
      t.belongs_to :claim, index: true, foreign_key: true
      t.belongs_to :commissioner, index: true, foreign_key: false
      t.timestamps null: false
    end

    add_foreign_key :rulings, :users, column: :commissioner_id
    add_index :rulings, [:claim_id, :commissioner_id], unique: true
  end
end
class Ruling < ActiveRecord::Base

  # ...

  validate :only_three_rulings_per_claim

  private 

    def only_three_rulings_per_claim
      if claim.rulings.size >= 3
        errors.add(:claim, "already has the max number of commissars")
      end
    end
end