如何为一个成员强制设置 has_many_through 关联?
Posted
技术标签:
【中文标题】如何为一个成员强制设置 has_many_through 关联?【英文标题】:How to make a has_many_through association mandatory for one member? 【发布时间】:2013-12-16 22:09:43 【问题描述】:我有以下型号:
class City < ActiveRecord::Base
has_many :cities_regions_relationships
has_many :regions, through: :cities_regions_relationships
end
class Region < ActiveRecord::Base
has_many :cities_regions_relationships
has_many :cities, through: :cities_regions_relationships
end
class CitiesRegionsRelationship < ActiveRecord::Base
belongs_to :city
belongs_to :region
validates :city_id, presence: true
validates :region_id, presence: true
end
我想要的是,如果没有与地区相关联的城市,就无法创建城市。但是,在尝试这样做之前,我必须能够在尚未保存的城市上建立关系。
我在控制台中试过这个(已经创建了一个区域)
c = City.new(name: "Test")
c.cities_region_relationship.build(region_id: Region.first.id)
c.save
但是,这会失败,因为关系没有 city_id(这很正常,因为我还没有保存城市,它没有 ID)。
我可以尝试其他方法,但我总是会遇到同样的问题:如何在尚未保存在数据库中的新对象上创建关系?
如果您对我最初的问题(强制城市至少有一个区域)有其他完全不同的解决方案,请不要犹豫,提出完全不同的建议。
【问题讨论】:
一个city
可以有多个regions
吗?
@AbM 是的。否则我可以使用has_many 和belongs_to,但不幸的是我的模型不是那么简单:(
查看SO post
【参考方案1】:
您不需要构建cities_region_relationship
。通过将region_ids
传递给一个新的City
实例,这将为您创建cities_region_relationship
。
你可以在控制台试试:
c = City.new(name: "Test", region_ids: [an array of existing region ids])
c.save
对于验证,您可以定义一个新的验证方法来检查 self.regions.blank?
是否像我上面评论中的 SO 帖子中提到的那样。
【讨论】:
不幸的是,这不起作用:c.errors
给了我#<ActiveModel::Errors:0x007ff163ab7870 @base=#<City id: nil, name: "Test", created_at: nil, updated_at: nil>, @messages=:cities_regions_relationships=>["is invalid"]>
。如您所见,该关系没有 city_id 并且无效。
我忘了提到要删除CitiesRegionsRelationship
中的验证,即您不需要validates :city_id, presence: true
或validates :region_id, presence: true
。您的验证仅在 City
模型中进行,以检查实例是否具有不是 blank
的 regions
数组以上是关于如何为一个成员强制设置 has_many_through 关联?的主要内容,如果未能解决你的问题,请参考以下文章