我有以下情况需要销毁与来自material
item_materials
相关联的project
个对象
begin
require 'bundler/inline'
rescue LoadError => e
$stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
raise e
end
gemfile(true) do
source 'https://rubygems.org'
gem 'rails', '4.2.7.1'
gem 'sqlite3'
end
require 'active_record'
require 'minitest/autorun'
require 'logger'
Minitest::Test = MiniTest::Unit::TestCase unless defined?(Minitest::Test)
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table :projects, force: true do |t|
end
create_table :items, force: true do |t|
t.integer :project_id
end
create_table :materials, force: true do |t|
end
create_table :item_materials, force: true do |t|
t.integer :item_id
t.integer :material_id
end
end
class Project < ActiveRecord::Base
has_many :items, inverse_of: :project
accepts_nested_attributes_for :items, allow_destroy: true
def clean_up_items
items.each do |item|
item.item_materials.each do |item_material|
item_material.mark_for_destruction
item_material.material.mark_for_destruction
end
end
save
end
end
class Item < ActiveRecord::Base
belongs_to :project, inverse_of: :items
has_many :item_materials, dependent: :destroy, inverse_of: :item
accepts_nested_attributes_for :item_materials, allow_destroy: true
end
class ItemMaterial < ActiveRecord::Base
belongs_to :item, inverse_of: :item_materials
belongs_to :material, inverse_of: :item_materials
accepts_nested_attributes_for :material, allow_destroy: true
end
class Material < ActiveRecord::Base
has_many :item_materials, dependent: :destroy, inverse_of: :material
end
class ProjectTest < Minitest::Test
def test_destroy_item_material_and_material
project = Project.create!
item = Item.create! project: project
material = Material.create!
item_material = ItemMaterial.create! item: item, material: material
assert project.reload.clean_up_items
assert Project.find_by_id(project)
assert Item.find_by_id(item)
assert_nil ItemMaterial.find_by_id(item_material)
assert_nil Material.find_by_id(material)
end
end
有没有办法在不手动打开交易的情况下完成,只需设置正确的关联选项?
答案 0 :(得分:0)
我认为这样做。
您只需要Material
,ItemMaterial
和:through
的正确关联。您需要更改关联才能使用class Project < ActiveRecord::Base
has_many :items
end
class Item < ActiveRecord::Base
belongs_to :project
has_many :item_materials, dependent: :destroy
has_many :materials, through: :item_materials
end
class Material < ActiveRecord::Base
has_many :item_materials, dependent: :destroy
has_many :items, through: :item_materials
end
class ItemMaterial < ActiveRecord::Base
belongs_to :item
belongs_to :material
end
textOn