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