sadaf2605
sadaf2605

Reputation: 7540

Deleting first occurrence from many to many collection entry at rails?

In many to many fields delete method is deleting all the occurrence of collection. Say I have:

class user < ActiveRecord::Base
  has_and_belongs_to_many :cars
end

class car < ActiveRecord::Base
  has_and_belongs_to_many :users
end

users and cars are many to many relationship, I have defined my users_cars table. Now user can have repetitive car entry as relation. For example:

Car: A,B,C User: U1,U2,U3

U1=[A,B,C,A,A,A,B]

Which can be implemented using many to many relationship, the way I have implemented. BUT, at the time when I want to delete one of the car entries of user the problem occurs.

User.cars.delete(car) #deletes all occurrence of car
User.cars.delete_at(User.cars.find_index(video_card)) #delete_at does not exist

Now how to resolve this?

Upvotes: 0

Views: 194

Answers (1)

Arslan Ali
Arslan Ali

Reputation: 17812

First of all, you can't call User.cars unless you have defined a class level method cars in your User model, but in this way, you would return all cars, and that - in no way - would make sense.

Second, delete_at is a method that works on Array objects, and expects an integer to be passed in. So as a little hack, you can turn your ActiveRecord::Associations object into an array, and then call delete_at method.

user = User.first
user.cars.to_a.delete_at(Car.last.id) # assuming that the last car belongs
# to the first user, something you would never do in actual
# production code.

Edit:

You can also try the following to achieve the same functionality:

user = User.first
user.cars.where("cars.id = ?", Car.first.id).first.delete

Edit 2:

For what you asked in comment, you can have a model for the table cars_users.

rails g model CarUser

class Car < ActiveRecord::Base
  has_many :cars_users
  has_many :users, through: car_users
end 

class User < ActiveRecord::Base
  has_many :cars_users
  has_many :cars, through: car_users
end

class CarUser < ActiveRecord::Base
  belongs_to :car
  belongs_to :user
end

And now, you can do:

CarUser.where("car_id = ? AND user_id = ?", Car.first.id, User.first.id).first.delete

Upvotes: 1

Related Questions