2016-07-29 18 views
2

ich eine Harke Aufgabe haben, die wie folgt aussieht:Active :: ReadOnlyRecord: Diff markiert ist als nur lesbar auf destroy_all

desc "Cleanup Snippets with Empty Diffs" 

task cleanup_snippets_with_empty_diffs: :environment do 
    Snippet.includes(:diffs).where(diffs: { body: "<div class=\"diff\"></div>"}).destroy_all 
end 

Doch wenn ich es laufen, bekomme ich diese:

$ rake cleanup_snippets_with_empty_diffs 
rake aborted! 
ActiveRecord::ReadOnlyRecord: Diff is marked as readonly 

Was könnte die Ursache dafür sein?

Edit 1

Beachten Sie, dass mein Snippet.rb Modell wie folgt aussieht:

class Snippet < ApplicationRecord 
    has_many :diffs, dependent: :destroy 
end 

Und Diff.rb wie folgt aus: mehrere

class Diff < ApplicationRecord 
    belongs_to :snippet 
end 

Antwort

5

Mit includes, Rails wird geprüft, ob die Verwendung Abfragen (unter Verwendung von preload) oder eine einzelne Linke t Outer-Join-Abfrage (mit eager_load). In Ihrem Fall wird Rails und daher einen LEFT OUTER JOIN verwenden, da Ihre WHERE-Klausel auf der Assoziation ist. Beachten Sie außerdem, dass über einen Join geladene Verknüpfungen als readonly markiert sind und die Ursache für den Fehler sind, den Sie erhalten. Die Lösung besteht darin, vor dem Aufruf destroy_allincludes zu left_joins zu wechseln und readonly(false) zu setzen.

Snippet.left_joins(:diffs).readonly(false).where(diffs: { body: "<div class=\"diff\"></div>"}).destroy_all 

HINWEIS

Ursprünglich dachte ich, Sie

tun konnte
Snippet.includes(:diffs).readonly(false).where(diffs: { body: "<div class=\"diff\"></div>"}).destroy_all 

aber aus irgendeinem Grund nicht funktioniert (und nicht genug Zeit atm zu untersuchen). In jedem Fall, da die Verwendung von includes zu einem LEFT OUTER JOIN führt, können Sie die obige Lösung verwenden, um das gewünschte Ergebnis zu erhalten.

+0

Ich liebe diese Idee. Aber es funktioniert nicht :( – marcamillion

+0

Denken Sie daran, ich verwende 'includes', nicht' Joins'. – marcamillion

+0

Sorry von 'Joins' Ich meinte * ein Join * und nicht unbedingt die' Joins' Methode. Bitte lesen Sie meine aktualisierte Antwort für weitere Erklärung und eine mögliche Lösung Danke –