Rails - has_one与两种可能模型之一的关联

时间:2016-03-23 08:00:29

标签: ruby-on-rails

关于Rails关联的问题,其中has_one关联是两种可能模型之一。就像一个多态关联,但反过来。

所以我有两种不同的银行账户,都属于UserConfig

class SwedishBankAccount
  belongs_to :user_config
end

class ForeignBankAccount
  belongs_to :user_config
end

问题是如何在UserConfig中管理此问题。它与has_oneSwedishBankAccount之间应该有ForeignBankAccount关联,但两者都不应该。{/ p>

4 个答案:

答案 0 :(得分:2)

您可以使用ploymorphic关系。在target_id模型

中添加target_typeUserConfig
class UserConfig < ActiveRecord::Base
  belongs_to :target, :polymorphic => true
end

然后您只需使用模型SwedishBankAccount As

class SwedishBankAccount < ActiveRecord::Base
  has_one :user_config, :as => :target
end

在模型ForeignBankAccount As

class ForeignBankAccount < ActiveRecord::Base
  has_one :user_config, :as => :target
end

答案 1 :(得分:1)

您可以为此模型创建抽象类BankAccount

class BankAccount < ActiveRecord::Base
  self.abstract_class = true
  belongs_to :user_config
end

class SwedishBankAccount < BankAccount
end

class ForeignBankAccount < BankAccount
end

class UserConfig < ActiveRecord::Base
  has_one :bank_account
end

这里没有BankAccount的表格,但您可以将模型的常用部分放在一起。

答案 2 :(得分:1)

正如zishe所暗示的那样,与抽象类有关联,但遗憾的是没有好主意(请参阅对该答案的评论)。 Vishal JAIN的答案可行,但我认为由于所有权的变更,这将使得更难以正确了解架构。

我最终与两种类型的银行账户建立了联系。一个丑陋的解决方案,但它是我能想到的最好的解决方案。如果其他人有更好的想法,请分享您的想法! :)

class UserConfig < ActiveRecord::Base
  has_one :swedish_bank_account
  has_one :foreign_bank_account

  enum bank_account_type [:swedish_bank_account, foreign_bank_account]

  # Returns bank account of type determined by bank_account_type.
  # Returns nil if no account is associated.
  def bank_account
    return swedish_bank_account if swedish_bank_account?
    return foreign_bank_account if foreign_bank_account?
  end
end

答案 3 :(得分:0)

你可以创建一个名为account的新模型,其中user_id是主键“no duplicates”,而account_id指向他在ForeignBankAccount或SweditshBankAccount中的记录。

这样您就可以确保一次没有用户拥有多个帐户。