In meiner Anwendung, diese „Planer“ (im Wesentlichen Artikel Ideen) folgt vorgegebene Vorlagen, in Markdown geschrieben, mit einigen spezifischen hier Syntax:generierte String wird nicht in der Datenbank speichern ... aber am Ende „A“ heftet und es wird
Please write your answer in the following textbox: [...]
Please write your answer in the following textarea:
...So here, on line, you should write one thing.
...Here, on line 2, you should write another.
...
...
...
Wesentlichen ist [...]
eine Texteingabe, und eine Gruppe von Linien mit ...
beginnen, eine TextArea-. Das ist nicht wirklich das Problem - es ist nur zu erklären, was ein Teil dieses Codes tut.
Auf Aktionen new
und edit
wird der Standardplaner Form dargestellt, mit den richtigen Feldern basierend auf der Vorlage (für new
) oder aktuelle Planer Körper (für edit
). Beim Speichern werden die Felder der Vorlage mit params [: fields] ausgefüllt, und der resultierende Markdown wird als Körper des Planers gespeichert. Ich hoffe, dass der Code nun folgen kann, wenn man diesen Kontext kennt. Es wird nur der relevante Controller-Code bereitgestellt, und es wird make_resourceful verwendet.
class Staff::PlannersController < StaffController
make_resourceful do
actions :all
before :create do
find_planner_format
if @planner_format
current_object.body = fields_in_template @planner_format.body
else
flash[:error] = 'Planner format not found!'
redirect_to staff_planners_path
end
current_object.user = @current_user
end
before :update do
current_object.body = fields_in_template(current_object.body)
end
end
private
def fields_in_template(template)
fields = params[:fields] || {}
if fields[:inline]
template.gsub! /\[\.\.\..*\]/ do
"[...#{fields[:inline].shift}]"
end
end
if fields[:block]
template.gsub! /^\.{3}.*(\n\.{3}.*)*$/ do
fields[:block].shift.split("\n").collect { |line|
"...#{line}"
}.join("\n")
end
end
current_object.body = template
end
end
Und nun, das Geheimnis: in der update
Aktion, Veränderungen des Körpers werden nicht gespeichert. Nach dem Debuggen, habe ich festgestellt, dass das Problem nicht nur in current_object.save nicht liegen, da das, was der folgenden before :update
Code tut man erwarten würde:
before :update do
current_object.body = 'test string'
end
In der Tat, auch wird dies das erwartete Ergebnis:
before :update do
current_object.body = fields_in_template(current_object.body) + 'a'
end
So, jetzt die Frage: Warum ist Rails so hartnäckig, dass es nicht das Ergebnis der Funktion speichern - und auch dann nur, wenn es von update
kommt? Mehr Debugging zeigte, dass das Objektattribut gesetzt ist und sogar behauptet, erfolgreich zu speichern, aber reload
das Objekt nach dem Speichern kehrt die Änderungen zurück.
Zuerst sah es aus wie die resultierende Zeichenfolge nur einen „vergifteten“ Variable der Art war, und dass die Zeichenfolge Wiederaufbau von „a“ entfernt, dass seltsamer Zustand anhängt. Der folgende Code, der ein "a" hinzufügen und es erneut entfernen sollte, konnte jedoch nicht gespeichert werden.
before :update do
new_body = fields_in_template(current_object.body) + 'a'
new_body.slice! -1
current_object.body = new_body
end
Das ist nur seltsam für mich. Was mache ich hier falsch, und was kann ich eventuell noch weiter machen? (Oder, wenn Sie geschehen, um sofort meinen Fehler zu sehen, würde so schön sein, auch ...)
EDIT: Nach SQL-Protokollen überprüft (nicht sicher, warum ich nicht diesen früher zu tun glaubte), es Scheint so zu sein, dass Rails das neue body-Attribut nicht als tatsächlich anders zu erkennen anerkennt, obwohl das Überprüfen der Zeichenfolge im Debugger dies bestätigt. Daher führt Rails nicht einmal eine UPDATE
Abfrage aus, sofern nicht etwas anderes geändert wird. In diesem Fall ist body
nicht enthalten.
Warum fügen Sie nicht etwas Protokollierung hinzu, um zu sehen, was gespeichert wird? – klochner
Ich würde auch current_object.body zu einem virtuellen Attribut ändern – klochner