我有模型 Province
和 User
,如果用户的地址中有该省,我需要阻止该省被删除。
由于模型 User.province
中包含以下问题,我可以做到 User
:
module MyAddressable
extend ActiveSupport::Concern
included do
has_one :address, as: :addressable, dependent: :destroy
has_one :city, through: :address
has_one :province, through: :city
has_one :zone, through: :city
accepts_nested_attributes_for :address, reject_if: :reject_address, allow_destroy: true
end
end
我正在尝试通过以下方式建立省和用户之间的关系,以便能够执行类似 Province.users
的操作:
has_many :users, through: :myaddresable
结果如下:
ActiveRecord::HasManyThroughAssociationNotFoundError: Could not find the association :myaddresable in model Province
如果我尝试将关系定义为
has_many :users, through: :addressable
能做到吗?如果是这样,正确的做法是什么?
答案 0 :(得分:1)
has_many :users, through: :addressable
不起作用,因为 Province
模型不了解 Address
模型。
我们可以通过Province
模型建立User
模型和Address
模型之间的关系。
以下设置适用于 rails 6
用户模型
class User < ApplicationRecord
has_one :address, as: :addressable, dependent: :destroy
has_one :city, through: :address
has_one :province, through: :city
end
省模式
class Province < ApplicationRecord
has_many :cities
has_many :users, through: :cities
end
城市模型
class City < ApplicationRecord
has_many :addresses
has_many :users,
through: :addresses,
source: :addressable,
source_type: 'User'
belongs_to :province
end
地址模型
class Address < ApplicationRecord
belongs_to :addressable, polymorphic: true
belongs_to :city
end
让我们假设根据模型关联正确定义了迁移。现在以下查询有效...
irb(main): > User.first.province
DEBUG -- : User Load (0.6ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT $1 [["LIMIT", 1]]
DEBUG -- : Province Load (0.3ms) SELECT "provinces".* FROM "provinces" INNER JOIN "cities" ON "provinces"."id" = "cities"."province_id" INNER JOIN "addresses" ON "cities"."id" = "addresses"."city_id" WHERE "addresses"."addressable_id" = $1 AND "addresses"."addressable_type" = $2 LIMIT $3 [["addressable_id", 1], ["addressable_type", "User"], ["LIMIT", 1]]
irb(main): > Province.first.users
DEBUG -- : Province Load (0.5ms) SELECT "provinces".* FROM "provinces" ORDER BY "provinces"."id" ASC LIMIT $1 [["LIMIT", 1]]
DEBUG -- : User Load (0.5ms) SELECT "users".* FROM "users" INNER JOIN "addresses" ON "users"."id" = "addresses"."addressable_id" INNER JOIN "cities" ON "addresses"."city_id" = "cities"."id" WHERE "cities"."province_id" = $1 AND "addresses"."addressable_type" = $2 [["province_id", 1], ["addressable_type", "User"]]
在您的情况下,由于 MyAddressable
问题已包含在 User
模型中,因此只需要定义其他关联和迁移。
希望这会有所帮助。谢谢。