Rails: 依赖销毁不会删除“通过”记录

创建于 2013-10-11  ·  3评论  ·  资料来源: rails/rails

gem 'activerecord', '4.0.0'
require 'active_record'
require 'minitest/autorun'
require 'logger'

ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Base.establish_connection(
  :adapter  => 'postgresql',
  :database => 'x'
)

ActiveRecord::Schema.define do
  create_table :users, :force => true do |t|
  end

  create_table :companies, :force => true do |t|
  end

  create_table :participations, :force => true do |t|
    t.integer :user_id
    t.integer :company_id
  end
end

class Company < ActiveRecord::Base
  has_many :participations, :dependent => :destroy, :autosave => true
  has_many :users, :through => :participations, :autosave => true
end


class Participation < ActiveRecord::Base
  belongs_to :company
  belongs_to :user
end

class User < ActiveRecord::Base
  has_many  :participations, :dependent => :destroy
  has_many  :companies, :through => :participations
end

class TestMe < MiniTest::Unit::TestCase
  def test_dependent_destroy
    c = Company.create!
    u = User.create!
    c.users << u
    c.destroy
    assert_equal [], Participation.all.to_a
    assert_equal [], User.all.to_a
  end
end

结果是:

vim test.rb

-- create_table(:users, {:force=>true})
D, [2013-10-11T17:58:44.115600 #10524] DEBUG -- :    (1.3ms)  DROP TABLE "users"
D, [2013-10-11T17:58:44.117995 #10524] DEBUG -- :    (2.2ms)  CREATE TABLE "users" ("id" serial primary key) 
   -> 0.0186s
-- create_table(:companies, {:force=>true})
D, [2013-10-11T17:58:44.119492 #10524] DEBUG -- :    (0.6ms)  DROP TABLE "companies"
D, [2013-10-11T17:58:44.120835 #10524] DEBUG -- :    (1.2ms)  CREATE TABLE "companies" ("id" serial primary key) 
   -> 0.0028s
-- create_table(:participations, {:force=>true})
D, [2013-10-11T17:58:44.122231 #10524] DEBUG -- :    (0.7ms)  DROP TABLE "participations"
D, [2013-10-11T17:58:44.123865 #10524] DEBUG -- :    (1.5ms)  CREATE TABLE "participations" ("id" serial primary key, "user_id" integer, "company_id" integer) 
   -> 0.0030s
MiniTest::Unit::TestCase is now Minitest::Test. From tmp/test.rb:41:in `<main>'
Run options: --seed 47789

# Running:

D, [2013-10-11T17:58:44.162282 #10524] DEBUG -- :    (0.2ms)  BEGIN
D, [2013-10-11T17:58:44.167369 #10524] DEBUG -- :   SQL (0.4ms)  INSERT INTO "companies" DEFAULT VALUES RETURNING "id"
D, [2013-10-11T17:58:44.167786 #10524] DEBUG -- :    (0.1ms)  COMMIT
D, [2013-10-11T17:58:44.169482 #10524] DEBUG -- :    (0.0ms)  BEGIN
D, [2013-10-11T17:58:44.173068 #10524] DEBUG -- :   SQL (0.5ms)  INSERT INTO "users" DEFAULT VALUES RETURNING "id"
D, [2013-10-11T17:58:44.173411 #10524] DEBUG -- :    (0.1ms)  COMMIT
D, [2013-10-11T17:58:44.182291 #10524] DEBUG -- :    (0.1ms)  BEGIN
D, [2013-10-11T17:58:44.194695 #10524] DEBUG -- :   SQL (2.8ms)  INSERT INTO "participations" ("company_id", "user_id") VALUES ($1, $2) RETURNING "id"  [["company_id", 1], ["user_id", 1]]
D, [2013-10-11T17:58:44.195175 #10524] DEBUG -- :    (0.1ms)  COMMIT
D, [2013-10-11T17:58:44.195378 #10524] DEBUG -- :    (0.1ms)  BEGIN
D, [2013-10-11T17:58:44.196501 #10524] DEBUG -- :   Participation Load (0.5ms)  SELECT "participations".* FROM "participations" WHERE "participations"."company_id" = $1  [["company_id", 1]]
D, [2013-10-11T17:58:44.198015 #10524] DEBUG -- :   SQL (0.5ms)  DELETE FROM "participations" WHERE "participations"."id" = $1  [["id", 1]]
D, [2013-10-11T17:58:44.198582 #10524] DEBUG -- :   SQL (0.3ms)  DELETE FROM "companies" WHERE "companies"."id" = $1  [["id", 1]]
D, [2013-10-11T17:58:44.198728 #10524] DEBUG -- :    (0.1ms)  COMMIT
D, [2013-10-11T17:58:44.199073 #10524] DEBUG -- :   Participation Load (0.1ms)  SELECT "participations".* FROM "participations"
D, [2013-10-11T17:58:44.199414 #10524] DEBUG -- :   User Load (0.1ms)  SELECT "users".* FROM "users"
F

Finished in 0.048269s, 20.7172 runs/s, 41.4345 assertions/s.

  1) Failure:
TestMe#test_dependent_destroy [tmp/test.rb:48]:
Expected: []
  Actual: [#<User id: 1>]

1 runs, 2 assertions, 1 failures, 0 errors, 0 skips
activerecord

最有用的评论

@dnagir :我认为这是一个设计问题。 将以下差异应用于您的 gist 使其变为绿色:

--- bar.rb  2013-10-12 15:11:42.058069352 +0200
+++ foo.rb  2013-10-12 15:25:51.316801856 +0200
@@ -30,11 +32,11 @@

 class Participation < ActiveRecord::Base
   belongs_to :company
-  belongs_to :user
+  belongs_to :user, dependent: :destroy
 end

 class User < ActiveRecord::Base
-  has_many  :participations, :dependent => :destroy
+  has_many  :participations
   has_many  :companies, :through => :participations
 end

所有3条评论

我不明白这有什么问题? 您的测试表明所有参与(加入记录)都被破坏了。 对于has_and_belongs_to_manyhas_many through关联,关联的记录永远不会因依赖而被删除/销毁。 根据API 文档

使用 has_and_belongs_to_many 和 has_many :through,如果你想自己删除关联的记录,你总是可以按照 person.tasks.each(&:destroy) 的方式做一些事情。

@dnagir :我认为这是一个设计问题。 将以下差异应用于您的 gist 使其变为绿色:

--- bar.rb  2013-10-12 15:11:42.058069352 +0200
+++ foo.rb  2013-10-12 15:25:51.316801856 +0200
@@ -30,11 +32,11 @@

 class Participation < ActiveRecord::Base
   belongs_to :company
-  belongs_to :user
+  belongs_to :user, dependent: :destroy
 end

 class User < ActiveRecord::Base
-  has_many  :participations, :dependent => :destroy
+  has_many  :participations
   has_many  :companies, :through => :participations
 end

@robin850是对的。

感谢您的报告。

此页面是否有帮助?
0 / 5 - 0 等级