5

I have 3 models:

Shedule

belongs_to :service

Service

belongs_to :user, :foreign_key => "owner"
has_many :shedules, :dependent => :destroy

User

has_many :services, :foreign_key => "owner", :dependent => :destroy
has_many :shedules, :through => :services, :foreign_key => "owner", :dependent => :destroy

Then i can see all shedules of user by my_user.shedules

My goal is deleting all shedules of user, then i try my_user.shedules.delete_all but get this error:

ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection: Cannot modify association 'User#shedules' because the source reflection class 'Shedule' is associated to 'Service' via :has_many.

After some googling i find this and some other similar posts, but all of them dont fit to my problem.

Of course i can delete this by iterating the user services like

my_user.services.each do |s|
    s.shedules.delete_all
end

But i'm interesting why my_user.shedules.delete_all dont't work.

Thanks!

Community
  • 1
  • 1
Parandroid
  • 513
  • 2
  • 11
  • Try removing the foreign_key from this `has_many :shedules, :through => :services, :foreign_key => "owner", :dependent => :destroy` –  Jun 04 '13 at 12:10
  • Unfortunately, the same error – Parandroid Jun 04 '13 at 12:19
  • http://stackoverflow.com/questions/1399394/dependent-destroy-on-a-has-many-through-association use `destroy` in order to trigger the callbacks of `:dependent => :destroy` – MrYoshiji Jun 04 '13 at 13:59
  • I want to delete only shedules, but not service which they belong to. – Parandroid Jun 04 '13 at 14:30

3 Answers3

4

Found an easier solution than presented here before.

Schedule.merge(my_user.schedules).delete_all

I prefer this because it is only one database query and I do not have to remember what the foreign key is named.

It works because:

Schedule.merge(my_user.schedules).to_sql == my_user.schedules.to_sql

lion.vollnhals
  • 1,762
  • 1
  • 11
  • 5
1

Try:-

my_user.shedules.destroy_all

OR

Shedule.delete_all(:owner => my_user.id)
Deepika
  • 826
  • 6
  • 14
  • This ans is working for me. You are not able to delete shedules MAy be because your shedules are also associated with services. – Deepika Jun 04 '13 at 12:21
  • Your table 'Shedule' is associated to 'Service' as well as with 'User' hence you are not able to delete the shedules using delete_all or destroy_all. – Deepika Jun 04 '13 at 12:24
  • I don't understand why. Shedule belongs to Service and Service belongs to User. This means that table Shedules has field service_id. So why can't i delete all shedules if nothing depends of it? – Parandroid Jun 04 '13 at 12:29
  • In terms of SQL i want: DELETE FROM shedules WHERE service_id in (SELECT id FROM services WHERE owner = ?). I dont see why it cant delete shedules. – Parandroid Jun 04 '13 at 12:31
  • Try this:- Shedule.delete_all(:user_id => my_user.id) – Deepika Jun 04 '13 at 12:42
  • Ooops! Use owner instead of user_id as your foreign_key is "owner". – Deepika Jun 04 '13 at 12:46
  • THere is no field 'owner' in table 'Shedule'. Link is: Shedule.service_id -> Service.owner -> User.id. – Parandroid Jun 04 '13 at 13:07
0

I'm not sure you can delete the schedules using the association. You can delete these records by simply finding them yourself.

Shedule.where(service_id: user.services.pluck(&:id)).delete_all
user.reload # optional

If you use this often you can define a method on User

def delete_schedules
  Shedule.where(service_id: user.services.pluck(&:id)).delete_all
end
phylae
  • 973
  • 1
  • 10
  • 18