Ruby on Rails has_many: уничтожая больше, чем следует
Я создаю приложение, в котором есть три основные модели и отношения между ними, по которым мне нужно отслеживать некоторые свойства:
schema.rb
create_table "entities", force: true do |t|
t.string "name"
t.string "label"
t.string "img"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "entities", ["name"], name: "index_entities_on_name", unique: true, using: :btree
create_table "entity_group_relationships", force: true do |t|
t.integer "entity_id"
t.integer "group_id"
t.integer "order"
t.string "label"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "entity_group_relationships", ["entity_id", "group_id"], name: "index_entity_group_relationships_on_entity_id_and_group_id", unique: true, using: :btree
create_table "entity_property_relationships", force: true do |t|
t.integer "entity_id"
t.integer "property_id"
t.integer "group_id"
t.integer "order"
t.string "label"
t.string "value"
t.integer "visibility"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "group_property_relationships", force: true do |t|
t.integer "group_id"
t.integer "property_id"
t.integer "order"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "group_property_relationships", ["group_id", "property_id"], name: "index_group_property_relationships_on_group_id_and_property_id", unique: true, using: :btree
add_index "group_property_relationships", ["group_id"], name: "index_group_property_relationships_on_group_id", using: :btree
add_index "group_property_relationships", ["property_id"], name: "index_group_property_relationships_on_property_id", using: :btree
create_table "groups", force: true do |t|
t.string "name"
t.string "default_label"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "groups", ["name"], name: "index_groups_on_name", unique: true, using: :btree
create_table "properties", force: true do |t|
t.string "name"
t.string "units"
t.string "units_short"
t.string "default_label"
t.string "default_value"
t.integer "default_visibility"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "properties", ["name"], name: "index_properties_on_name", unique: true, using: :btree
Entity.rb
class Entity < ActiveRecord::Base
has_many :entity_property_relationships
has_many :entity_group_relationships
has_many :properties,
through: :entity_property_relationships,
inverse_of: :entities
has_many :groups,
through: :entity_group_relationships,
inverse_of: :entities
validates :name,
presence: true
#rest omitted
end
Property.rb
class Property < ActiveRecord::Base
has_many :group_property_relationships
has_many :entity_property_relationships
has_many :entities,
through: :entity_property_relationships,
inverse_of: :properties
has_many :groups,
through: :group_property_relationships,
inverse_of: :properties
validates :name, presence: true
#rest omitted
end
Group.rb
class Group < ActiveRecord::Base
has_many :group_property_relationships
has_many :entity_group_relationships
has_many :entities,
through: :entity_group_relationships,
inverse_of: :groups
has_many :properties,
through: :group_property_relationships,
inverse_of: :groups
validates :name,
presence: true
#rest omitted
end
entity_property_relationship.rb
class EntityPropertyRelationship < ActiveRecord::Base
belongs_to :entity
belongs_to :property
validates :entity_id,
presence: true
validates :property_id,
presence: true
validates :order,
presence: :true
#rest omitted
end
entity_group_relationship.rb
class EntityGroupRelationship < ActiveRecord::Base
belongs_to :entity
belongs_to :group
validates :entity_id,
presence: true
validates :group_id,
presence: true
validates :order,
presence: true
#rest omitted
end
group_property_relationship.rb
class GroupPropertyRelationship < ActiveRecord::Base
belongs_to :group
belongs_to :property
validates :group_id,
presence: true
validates :property_id,
presence: true
validates :order,
presence: true
#rest omitted
end
Эта проблема
Поведение, которое я пытаюсь предотвратить, это когда property
удалено, все EntityPropertyRelationships
которые разделяют одно и то же Entity
а также Group
также удаляются. Это не так для GroupPropertyRelationships
ни для EntityGroupRelationships
и из всего, что я вижу и понимаю, эти отношения были настроены так, чтобы вести себя одинаково.
Я тестирую это с помощью rspec, вот несколько тестов.
Тест 1:
it "should still own non-destroyed properties" do
@entity = Entity.create!(name: "entity")
@property1 = Property.create!(name: "property1")
@property2 = Property.create!(name: "property2")
@group = Group.create!(name: "group")
@group.own!(@property1)
@group.own!(@property2)
@entity.own!(@group)
@entity.utilizes?(@property1).should eq(true)
@entity.utilizes?(@property2).should eq(true)
@property1.destroy
@entity.utilizes?(@property1).should eq(false)
@entity.utilizes?(@property2).should eq(true)
@group.owns?(@property1).should eq(false)
@group.owns?(@property2).should eq(true)
end
Тест 1 - это тест, который не проходит. entity
должен еще utilize
property
- utilizes?()
проверяет, что EntityPropertyRelationship
существует между entity
и данный property
,
Тест 2
it "should still own non-destroyed groups" do
@entity = Entity.create!(name: "entity")
@group1 = Group.create!(name: "group1")
@group2 = Group.create!(name: "group2")
@entity.own!(@group1)
@entity.own!(@group2)
@entity.owns?(@group1).should eq(true)
@entity.owns?(@group2).should eq(true)
@group1.destroy
@entity.owns?(@group1).should eq(false)
@entity.owns?(@group2).should eq(true)
end
Тест 3
it "should still utilize non-destroyed groups' properties" do
@entity = Entity.create!(name: "entity")
@group1 = Group.create!(name: "group1")
@group2 = Group.create!(name: "group2")
@property1 = Property.create!(name: "property1")
@property2 = Property.create!(name: "property2")
@group1.own!(@property1)
@group2.own!(@property2)
@entity.own!(@group1)
@entity.own!(@group2)
@entity.owns?(@group1).should eq(true)
@entity.owns?(@group2).should eq(true)
@entity.utilizes?(@property1).should eq(true)
@entity.utilizes?(@property2).should eq(true)
@group1.destroy
@entity.owns?(@group1).should eq(false)
@entity.owns?(@group2).should eq(true)
@entity.utilizes?(@property1).should eq(false)
@entity.utilizes?(@property2).should eq(true)
end
Тест 2 и Тест 3 проходят нормально. Я не могу придумать, как насчет этих отношений оправдывает призыв уничтожить каждого EntityPropertyRelationship
даже где property_id
не является идентификатором свойства, которое будет уничтожено изначально. Есть ли что-то, что мне нужно изменить в отношениях, или есть способ, которым я мог бы предотвратить это с помощью destroy_callbacks?
1 ответ
Ой! Я только что нашел проблему. Я никогда не думал, что это будет там, где это было, вот почему потребовалось так много времени, чтобы найти. В моем GroupPropertyRelationships
Я имел after_destroy
это разрушило бы EntityPropertyRelationships
для каждого из этого Group's
связанный Entities
, Это должно просто разрушать EntityPropertyRelationships
где group_id
и property_id
такие же как текущий GroupPropertyRelationship
быть уничтоженным. Я заменил after_destroy
код для GroupPropertyRelationship
с:
after_destroy do |r|
EntityPropertyRelationship.destroy_all group_id: r.group_id, property_id: r.property_id
end
Это должно быть ошибка копирования-вставки.