Я думаю, у вас есть две проблемы здесь.
- Сохранение ошибок проверки через перенаправление
- Повторное заполнение полей формы, чтобы пользователю не приходилось вводить всю информацию снова.
Обе эти вещи связаны.
Ошибки проверки обычно отображаются с помощью метода error_msg_for, который воздействует на объект. Обычно предоставляется контроллером как переменная экземпляра объекта, которая не может быть сохранена. Эта же переменная экземпляра используется для повторного заполнения формы.
Во время перенаправления контроллер обычно создает экземпляр переменной экземпляра, используя хэш params. Поэтому любая информация, используемая для определения причины сбоя сохранения, теряется. Обычные ресурсы будут отображаться при сбое сохранения и перенаправляться при успехе, это приводит к двум вещам.
- Экземпляр объекта передается в error_msg_ для создания этого красивого единообразного блока ошибок.
- Экземпляр объекта используется для заполнения полей формы, что позволяет вашему пользователю редактировать только то, что необходимо.
Я не очень хорошо знаю Beast, поэтому я не уверен, является ли форма для создания потоков активной моделью записи. Но следующее даст вам представление о том, как обойти вашу проблему. Для этого потребуется изменить локальную копию плагина Beast, поэтому, если вы используете инструмент для его обновления, ваши изменения могут быть потеряны.
Я использовал следующие методы, чтобы решить ваши проблемы с проверкой. Предполагая, что форма, о которой вы говорите, основана на модели, они должны предоставить вам все необходимое для повторного заполнения формы.
По сути, вы сохраняете поверхностную копию объекта с ошибками во флеш-хэше, используя clone_with_errors. Вы должны использовать поверхностную копию, иначе вы столкнетесь с проблемами при отображении ошибок для записей с несколькими ассоциациями.
Затем я использую my_error_msg_for, который использует те же опции, что и стандартный error_msg_for, для создания html сообщений об ошибках. Я написал это только потому, что по какой-то причине стандартный метод error_msg_for не работал с объектами, хранящимися в хэше. Это почти идентично официальной исходной версии error_msg_for, которая вызывала беспокойство.
/ приложение / контроллеры / examples_controller.rb
class ExamplesController < ApplicationController
def update
...
if @example.save
regular action
else
flash[:errors] = clone_with_errors(@example)
respond_to do |format|
format.html redirect_to(@example)
end
end
end
/ приложение / просмотров / примеры / show.html.erb
<div id="error">
<% if flash[:errors] && !flash[:errors].empty? then -%>
<p ><%= my_error_msg_for flash[:errors] %></p>
<% end -%>
</div>
...
Вот код, который вам нужен, чтобы все это заработало.
application_controller.rb
def clone_with_errors(object)
clone = object.clone
object.errors.each{|field,msg| clone.errors.add_to_base(msg)}
return clone
end
application_helper.rb
def _error_msg(*params)
options = params.extract_options!.symbolize_keys
if object = options.delete(:object)
objects = [object].flatten
else
objects = params.collect {|object_name| instance_variable_get("@#{object_name}") }.compact
end
count = objects.inject(0) {|sum, this| sum + this.errors.count }
unless count.zero?
html = {}
[:id, :class].each do |key|
if options.include?(key)
value = options[key]
html[key] = value unless value.blank?
else
html[key] = 'errorExplanation'
end
end
options[:object_name] ||= params.first
options[:header_message] = "#{pluralize(count, 'error')} prohibited this #{options[:object_name].to_s.gsub('_', ' ')} from being saved" unless options.include?(:header_message) && !options[:header_messag].nil?
options[:message] ||= 'There were problems with the following fields:' unless options.include?(:message) && !options[:message].nil?
error_messages = objects.sum {|this| this.errors.full_messages.map {|msg| content_tag(:li, msg) } }.join
contents = ''
contents << content_tag(options[:header_tag] || :h2, options[:header_message]) unless options[:header_message].blank?
contents << content_tag(:p, options[:message]) unless options[:message].blank?
contents << content_tag(:ul, error_messages)
content_tag(:div, contents, html)
else
''
end
end
def my_error_msg_for(params)
_error_msg_test :object_name => params[:object].class.name.gsub(/([a-z])([A-Z])/,'\1 \2').gsub(/_/, " "),
:object => params[:object], :header_message => params[:header_message], :message => params[:message]
end