В моем приложении эти «планировщики» (по сути, идеи статей) следуют заданным шаблонам, написанным в Markdown, с некоторым определенным синтаксисом здесь:
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.
...
...
...
По сути, [...]
является текстовым вводом, а группа строк, начинающаяся с ...
, является текстовой областью. Дело не в этом - просто для объяснения того, что делает этот код.
При действиях new
и edit
отображается стандартная форма планировщика с правильными полями на основе шаблона (для new
) или текущего тела планировщика (для edit
). При сохранении поля шаблона заполняются параметрами params [: fields], а полученная уценка сохраняется как тело планировщика. Надеюсь, что теперь можно следовать коду, зная этот контекст. Предоставляется только соответствующий код контроллера, и он использует make_resourceful.
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
А теперь загадка: в действии update
изменения в теле не сохраняются. После отладки я определил, что проблема заключается не только в current_object.save, поскольку следующий код before :update
делает то, что вы ожидаете:
before :update do
current_object.body = 'test string'
end
На самом деле, даже это дает ожидаемый результат:
before :update do
current_object.body = fields_in_template(current_object.body) + 'a'
end
Итак, теперь вопрос: почему Rails настолько настойчив, что не сохраняет результат функции - и даже тогда, только когда он исходит от update
? Дальнейшая отладка показала, что атрибут объекта установлен и даже утверждает, что успешно сохранил, но reload
объект после сохранения отменяет изменения.
Сначала это выглядело так, как будто полученная строка была просто «отравленной» переменной, и перестройка строки путем добавления «а» удалила это странное состояние. Однако следующий код, который должен добавить «а» и удалить его снова, также не удалось сохранить.
before :update do
new_body = fields_in_template(current_object.body) + 'a'
new_body.slice! -1
current_object.body = new_body
end
Это просто странно для меня. Что я здесь делаю не так, и что я могу сделать для дальнейшей отладки? (Или если бы вы случайно увидели мою ошибку, это тоже было бы неплохо ...)
РЕДАКТИРОВАТЬ: После проверки журналов SQL (не уверен, почему я не думал делать это раньше), кажется, что Rails, похоже, не признает новый атрибут body как фактически отличающийся, хотя проверка строки в отладчике подтверждает, что это так. Таким образом, Rails даже не запускает запрос UPDATE
, если не изменено что-то еще, в этом случае body
не включается.