如果我有两个模型之间的关系has_and_belongs_to_many
,比方说Users
和Accounts
,我可以要求一个User
至少有一个Account
,又如何呢?Rails的做一个模型需要另一种模式
此外,使用has_and_belongs_to_many
关系,Account
可能不具有User
?
我需要的是在那里Accounts
可以生活在自己,属于Billers
的关系,但他们也可以属于Users
如果User
一个报了名。这是可能的,以及如何?
如果我有两个模型之间的关系has_and_belongs_to_many
,比方说Users
和Accounts
,我可以要求一个User
至少有一个Account
,又如何呢?Rails的做一个模型需要另一种模式
此外,使用has_and_belongs_to_many
关系,Account
可能不具有User
?
我需要的是在那里Accounts
可以生活在自己,属于Billers
的关系,但他们也可以属于Users
如果User
一个报了名。这是可能的,以及如何?
我个人会放弃HABTM。相反,我会使用has_many :though=>
您需要创建两个新模型,account_users和account_billers。您可能已经有了HABTM的连接表,但是这会将它们暴露为模型,因此它们将需要ID字段。
所以,你最终会像下面这样:
class Account < ActiveRecord::Base
has_many :account_billers
has_many :account_users
has_many :billers, :through=> :account_billers
has_many :users, :through=> :account_users
end
class User < ActiveRecord::Base
has_many :account_users
has_many :accounts, :through=>:account_users
validates :accounts, :length => { :minimum => 1}
end
class Biller < ActiveRecord::Base
has_many :account_billers
has_many :accounts, :through=>:account_billers
validates :accounts, :length => { :minimum => 1}
end
class AccountUser < ActiveRecord::Base
belongs_to :user
belongs_to :account
end
class AccountBiller < ActiveRecord::Base
belongs_to :biller
belongs_to :account
end
要验证至少一种关联的存在,你可能想使用一个custom validation method,像
class User < ActiveRecord::Base
has_and_belongs_to_many :accounts
validate :require_at_least_one_account
private
def require_at_least_one_account
errors.add(:accounts, "must amount to at least one") if accounts.size < 1
end
end
(虽然这带来了如何在用户之间共享帐户的问题)
对于第二个问题,看起来像polymorphic associations是wha你正在寻找,但你不能直接与HABTM的关系做到这一点,你必须将其改为has_many :through
并引入联合模型。
你可以使用多态,但没有好的方法来做多态的FK约束。如果user1521444对模型和关系还没有很好的把握,我会避免这种情况。 – 2012-07-13 01:43:05
有了多态关联,看起来好像您可以拥有一个属于用户或Biller的帐户,但同一个帐户是否属于多态关联? – macdamaniac 2012-07-13 16:13:57
如果您可以同时拥有属于用户和账单的账户,我不认为AR支持这种开箱即用的方式。你可以检查这个问题http://stackoverflow.com/questions/3209322/rails-polymorphic-has-many – HargrimmTheBleak 2012-07-13 16:23:41
这将设置一个要求,即用户和账单持有人拥有账户,但账户可能无法拥有用户或账单持有人。 – 2012-07-12 19:36:55