0

J'ai un has_and_belongs_to_many en utilisant has_many entre les utilisateurs et les espaces de travail.Rails HABTM has_many détruire l'erreur

user.rb

class User < ActiveRecord::Base 
    has_many :user_workspaces, dependent: :destroy 
    has_many :workspaces, through: :user_workspaces 
    before_destroy :delete_workspaces 

def delete_workspaces 
    self.workspaces.each(&:destroy) 
end 

workspace.rb

class Workspace < ActiveRecord::Base 
    has_many :user_workspaces 
    has_many :users, through :user_workspaces 
end 

user_workspaces classe et migration:

class UserWorkspace < ActiveRecord::Base 
    self.table_name = "user_workspaces" 
    belongs_to :user 
    belongs_to :workspace 
end 

class CreateUsersAndWorkspaces < ActiveRecord::Migration 
    def change 
    create_table :users_workspaces, id: false do |t| 
     t.belongs_to :user, index: true 
     t.belongs_to :workspace, index: true 
     t.boolean :admin, default: true 
    end 
    end 
end 
    class RenameUsersWorkspaces < ActiveRecord::Migration 
    def change 
    rename_table('users_workspaces', 'user_workspaces') 
    end 
end 

Je veux que ce test à la fois passer:

should "destroy all associatios and objects" do 
    user = User.create!(attributes_for(:user)) 
    w = user.workspaces.create!(attributes_for(:workspace)) 
    user.destroy 
    assert UserWorkspace.all.empty? #asser there are no associations 
end 

qui me donne l'erreur

ActiveRecord :: StatementInvalid: SQLite3 :: SQLException: pas de colonne: user_workspaces .: DELETE FROM "user_workspaces" WHERE "user_workspaces". "" =?

should "destroy association when destroying workspace" do 
     user = User.create!(attributes_for(:user)) 
     w = user.workspaces.create!(attributes_for(:workspace)) 
     w.destroy 
     assert UserWorkspace.all.empty? 
end 

Comment puis-je couvrir les deux scénarios? détruire un utilisateur détruit l'association et les espaces de travail, détruire l'espace de travail détruit également l'association

Répondre

0

Selon http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html juste besoin d'ignorer la table de jointure.

Workspace.rb a dépendante de détruire, de détruire uniquement la jointure (comportement prévu de détruire)

has_many :users,    through:  :user_workspaces, 
            inverse_of: :workspaces, 
            dependent: :destroy 

puis user.rb conserve les fonctions delete_workspaces, mais ajoute en fonction:: détruire, de détruire aussi l'association.

user.rb

before_destroy: :delete_workspaces 
    has_many :workspaces,   through: :user_workspaces,         
            dependent: :destroy 

def delete_workspaces 
    self.workspaces.each(&:destroy) 
end 

maintenant à la fois test passe.