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)
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.
CodePudding user response:
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:
- 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)
- Make the query a bit different to be able to use the
destroy_all
:
EmailNotificationCodePercentage.merge(@campaign.email_notification_code_percentage_trackers).destroy_all