我有型号Province
和User
,如果用户的地址中有省,我需要阻止删除该省。
由于型号User
中包含以下问题,我可以执行User.province
:
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
这能做到吗?如果是这样的话,正确的做法是什么?
has_many :users, through: :addressable
不起作用,因为Province
模型对Address
模型一无所知。
我们可以通过Address
模型来建立Province
模型和User
模型之间的关系。
以下设置适用于轨道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
模型中,因此只需要定义其他关联和迁移。
希望这能有所帮助。非常感谢。