user1466717
user1466717

Reputation: 789

ActiveRecord destroy method - wrong number of arguments (0 for 1)

I have 3 tables and 3 models:

Car.rb

  has_many :cars_domains, :dependent => :delete_all
  has_many :domains, :through => :cars_domains

Domain.rb

has_many :cars_domains
has_many :cars, :through => :cars_domains

and cars_domain.rb

class CarsDomain < ActiveRecord::Base
  belongs_to :car
  belongs_to :domain

  attr_accessible :car_id, :domain_id
end

class CreateCarsDomains < ActiveRecord::Migration
  def change
    create_table :cars_domains, :id => false do |t|
      t.references :car, :domain
      t.timestamps
    end

    add_index :cars_domains, [:car_id, :domain_id]
  end
end

One car can be in some domains. When I create a car and tied to a domain, then all is well.

But when I try destroy from cars_domains table, I have errors:

CarsDomain.where(:car_id => 2, :domain_id => 1).destroy
ArgumentError: wrong number of arguments (0 for 1)

Or

 CarsDomain.where(:car_id => 2, :domain_id => 1).destroy_all

  CarsDomain Load (0.5ms)  SELECT "cars_domains".* FROM "cars_domains" WHERE "cars_domains"."car_id" = 2 AND "cars_do
mains"."domain_id" = 1

   (0.2ms)  SAVEPOINT active_record_1
Could not log "sql.active_record" event. NoMethodError: undefined method `name' for nil:NilClass
   (0.3ms)  ROLLBACK TO SAVEPOINT active_record_1
ActiveRecord::StatementInvalid: PGError: ERROR:  zero-length delimited identifier at or near """"
LINE 1: DELETE FROM "cars_domains" WHERE "cars_domains"."" = $1
                                                        ^
: DELETE FROM "cars_domains" WHERE "cars_domains"."" = $1
        from /usr/local/lib/ruby/gems/1.9.1/gems/activerecord-3.1.3/lib/active_record/connection_adapters/postgresql_
adapter.rb:1062:in `prepare'

What's wrong?

UPD:

CarsDomain.destroy_all(:car_id => 2, :domain_id => 1)

CarsDomain Load (0.9ms) SELECT "cars_domains".* FROM "cars_domains" WHERE "cars_domains"."car_id" = 2 AND "cars_do mains"."domain_id" = 1 (0.2ms) SAVEPOINT active_record_1 Could not log "sql.active_record" event. NoMethodError: undefined method `name' for nil:NilClass (0.2ms) ROLLBACK TO SAVEPOINT active_record_1 ActiveRecord::StatementInvalid: PGError: ERROR: zero-length delimited identifier at or near """" LINE 1: DELETE FROM "cars_domains" WHERE "cars_domains"."" = $1 ^ : DELETE FROM "cars_domains" WHERE "cars_domains"."" = $1

UPD 2

I think that problem in ID ---- create_table :cars_domains, :id => false. Because Destroy method need it.

Upvotes: 3

Views: 5486

Answers (4)

user1466717
user1466717

Reputation: 789

Problem was in : create_table :cars_domains, :id => false do |t|

Correct variant is: create_table :cars_domains do |t|

And CarsDomain.where(:car_id => params[:car_id], :domain_id => params[:domain_id]).destroy_all

Upvotes: 2

Nucc
Nucc

Reputation: 1031

Because you got more entries, and it belongs to CarsDomain. CarsDomain#destroy expects an id, so that's why you got this message. Use destory_all with condition!

CarsDomain.destroy_all(:car_id => 2, :domain_id => 1)

Upvotes: 5

eileencodes
eileencodes

Reputation: 183

In your Car model (car.rb) you have the dependent set to :delete_all, when it should be :destroy, meaning has_many :cars_domains, :dependent => :destroy

If your domain is also dependent you need to add :dependent => :destroy to your domain model as well.

Upvotes: 3

apneadiving
apneadiving

Reputation: 115521

You're working on a collection, so use destroy_all.

See doc.

Upvotes: 4

Related Questions