2017-01-20 5 views
0

私はちょうど設定し、トランザクションを手動で開けずにいることを達成する方法はあり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 

から来るitem_materialsに関連するmaterialオブジェクトを破壊するために必要な次のような場合があります適切な関連付けオプション

答えて

0

これはやると思います。

Item,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 
+0

こんにちは、変更を加えてコードを実行しましたか?私は試しましたが、今は 'item_materials 'さえ破壊されません。 – RPinel

+0

私はちょうどあなたがまだaccepts_nested_attribute_forと他のコード –

+0

を返すためにありがとうアソシエーションの変更を提案しました。より具体的になりますか? – RPinel

関連する問題