我有一个地方模型has_many类别通过category_tags。 我对标签进行了验证,以确保它具有地点和类别,并避免在一个地方有两次相同的类别。用has_many关系保存对象
型号:
class PlaceCategory < ActiveRecord::Base
has_many :place_category_tags, inverse_of: :place_category
has_many :places, through: :place_category_tags
end
class Place < ActiveRecord::Base
has_many :place_category_tags, inverse_of: :place
has_many :place_categories, through: :place_category_tags
end
class PlaceCategoryTag < ActiveRecord::Base
belongs_to :place
belongs_to :place_category
validates :place_id, presence: true
validates :place_category_id, presence: true, uniqueness: {scope: :place_id}
end
我也有一个指标我place_category_tags表,以确保在数据库级别的唯一性:
add_index "place_category_tags", ["place_id", "place_category_id"], name: "index_place_category_tags_on_place_id_and_place_category_id", unique: true, using: :btree
我的问题是,当我保存的标签一个新的地方。验证在保存位置之前在标签上执行,因此它失败,因为place_id为空。
2.1.5 :001 > place = Place.new()
=> #<Place id: nil, name: "erg", created_at: nil, updated_at: nil>
2.1.5 :002 > place.place_category_tags.build(place_category_id: 3)
=> #<PlaceCategoryTag id: nil, place_id: nil, place_category_id: 3, created_at: nil, updated_at: nil>
2.1.5 :003 > place.save
(0.3ms) BEGIN
(0.3ms) BEGIN
PlaceCategoryTag Exists (0.5ms) SELECT 1 AS one FROM "place_category_tags" WHERE ("place_category_tags"."place_category_id" = 3 AND "place_category_tags"."place_id" IS NULL) LIMIT 1
PlaceCategoryTag Exists (0.5ms) SELECT 1 AS one FROM "place_category_tags" WHERE ("place_category_tags"."place_category_id" = 3 AND "place_category_tags"."place_id" IS NULL) LIMIT 1
(0.2ms) ROLLBACK
(0.2ms) ROLLBACK
=> false
2.1.5 :004 > place.errors
=> #<ActiveModel::Errors:0x0000000384e8a8 @base=#<Place id: nil, created_at: nil, updated_at: nil>, @messages={:"place_category_tags.place_id"=>["can't be blank"]}>
我搜索了类似的问题,但我发现的是,我不得不添加我的地方的的has_many place_category_tags,这是我做的inverse_of选项,但它并没有解决我的问题。
我也试图在代替place_id和place_category_id地方,place_category执行验证:
validates :place, presence: true
validates :place_category, presence: true, uniqueness: {scope: :place}
,似乎工作,但问题是,当我尝试创建唯一性验证不再执行两个相同的place_category_tags,和我在数据库级别的错误:
ActiveRecord::RecordNotUnique (PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_place_category_tags_on_place_id_and_place_category_id"
DETAIL: Key (place_id, place_category_id)=(49, 3) already exists.
: INSERT INTO "place_category_tags" ("created_at", "place_category_id", "place_id", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"):
app/controllers/backend/places_controller.rb:12:in `create'
是否有人有什么错我的代码的想法?
此外,我发现验证在第二个例子中完全被跳过非常奇怪。如果有人有什么事情的想法,那简直太好了:)
编辑:我使用的Rails 4.1.8和Ruby 2.1.5p273
是的,这工作,因为这个地方已经创建并有一个ID,但对我来说,我呼吁在新的动作新,然后在我的控制器的创建acion创建的地方。标签在表单中作为嵌套属性传递。 –