Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Cannot destroy a model with a has_many through assocation

I have the following models linked through a has_many :through associaton. Below is the following models

class Campaign
  has_many :email_notification_code_percentages, dependent: :destroy
  has_many :email_notification_code_percentage_trackers, through: :email_notification_code_percentages
end

class EmailNotificationCodePercentage < ApplicationRecord
  belongs_to :campaign
  has_many :email_notification_code_percentage_trackers, dependent: :destroy
end

class EmailNotificationCodePercentageTracker < ApplicationRecord
  belongs_to :email_notification_code_percentage
end


When I try execute the following @campaign.email_notification_code_percentage_trackers.destroy_all I get the following error:

Cannot modify association ‘Campaign#email_notification_code_percentage_trackers’ because the source reflection class ‘EmailNotificationCodePercentageTracker’ is associated to ‘EmailNotificationCodePercentage’ via :has_many. (ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection)

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

What is the issue here? This should be a simple has many through association as defined through the rails examples. What am I missing here? This looks correct to me.

>Solution :

This is the expected behavior, as you can read in the API docs (https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html):

An important caveat with going through has_one or has_many
associations on the join model is that these associations are
read-only.

Associations with the :through option or defined via the has_and_belongs_to_many macro are a bit special.

So, a couple of alternative ways:

  1. Iterate over each elem:
# be careful if the association is very large, you can run into some memory or timeout issues
@campaign.email_notification_code_percentage_trackers.each(&:destroy)
  1. Make the query a bit different to be able to use the destroy_all:
EmailNotificationCodePercentage.merge(@campaign.email_notification_code_percentage_trackers).destroy_all
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading