处理一个用户模型的 has_one 和 has_many 关联

Posted

技术标签:

【中文标题】处理一个用户模型的 has_one 和 has_many 关联【英文标题】:Dealing with has_one and has_many associations with one user model 【发布时间】:2021-12-31 13:40:12 【问题描述】:

我目前有一个用户模型

class User < ApplicationRecord
  has_one :leases
end

租赁模式

class Lease < ApplicationRecord  
  belongs_to :tenant, class_name: 'User'
  belongs_to :landlord, class_name: 'User'
end

和租赁模式

class Rental < ApplicationRecord
  has_one :lease, dependent: :destroy
end

我只有一个用户模型支持租户和房东。

我面临的问题是房东可以与许多不同的租户签订多个租约,但租户一次只能拥有一个租约。

我对如何正确构建它感到有些困惑。我是否应该与 User 模型和 Lease 模型而不是 has_one 有一个 has_many 关系,然后只是一个方法说在 User 模型上租用来获得租户的租约? 我想要的是类似的东西

tenant.lease

landlord.leases

我可以吗?

class User < ApplicationRecord
  has_one :lease, foreign_key: "tenant_id"
  has_many :leases, foreign_key: "landlord_id"
end

这似乎可行,但我不确定它是否正确。

【问题讨论】:

如果你为租客和房东分开桌子,那会让你的生活更轻松,至少我会那样做。 您考虑过使用 STI 吗?这将启用多个类,每个类都有自己的has_onehas_many,但它们会在后台使用同一个表。 【参考方案1】:

使用STI,您可以拥有以下模型

==> user.rb <==
class User < ApplicationRecord
end

==> landlord.rb <==
class Landlord < User
  has_many :leases
end

==> tenant.rb <==
class Tenant < User
  has_one :lease
end

==> lease.rb <==
class Lease < ApplicationRecord
  belongs_to :tenant
  belongs_to :landlord
end

然后你可以做类似的事情

irb(main):003:0> landlord = Landlord.create(name: 'the landlord')
=> #<Landlord id: 5, name: "the landlord", type: "Landlord", created_at: "2022-01-03 22:16:56", updated_at: "2022-01-03 22:16:56">

irb(main):004:0> tenant = Tenant.create(name: 'the tenant')
=> #<Tenant id: 6, name: "the tenant", type: "Tenant", created_at: "2022-01-03 22:17:09", updated_at: "2022-01-03 22:17:09">

irb(main):005:0> lease = Lease.create(tenant: tenant, landlord: landlord)
=> #<Lease id: 3, tenant_id: 6, landlord_id: 5, created_at: "2022-01-03 22:17:28", updated_at: "2022-01-03 22:17:28">

irb(main):006:0> tenant.lease
=> #<Lease id: 3, tenant_id: 6, landlord_id: 5, created_at: "2022-01-03 22:17:28", updated_at: "2022-01-03 22:17:28">

irb(main):007:0> landlord.leases
=> #<ActiveRecord::Associations::CollectionProxy [#<Lease id: 3, tenant_id: 6, landlord_id: 5, created_at: "2022-01-03 22:17:28", updated_at: "2022-01-03 22:17:28">]>

要完成此操作,您只需向您的 User 模型添加一个 type 列,其余的工作将由 Rails 完成。

【讨论】:

【参考方案2】:

在我看来,您应该使用has_many 方法。由于房东和租户都是用户。代替使用 tenant_idlandlord_id,您必须使用 'user_id' 并识别用户,使用 user_type 即租户和地主。

只是意见!!

【讨论】:

以上是关于处理一个用户模型的 has_one 和 has_many 关联的主要内容,如果未能解决你的问题,请参考以下文章

如何在同一模型中进行 has_many 和 has_one 关联?

has_one 与用户和客户的关联以及 Rails 视图表单

Rails 中具有相同键的两个表而不是 has_one 关系

Thinkphp学习日记:关联模型

Rails ActiveRecord 关联“has_many,每个都有 has_one”

Rails API 将 has_one: 图像从模型项推送到 Cloudinary 但不能