Как передать ошибки формы в сессию или флэш? [Rails 2.3.5]
У меня есть действие создания для формы, которая потенциально генерирует ошибки (т.е. имя отсутствует), а затем перенаправляет.
Проблема в том, что когда происходит перенаправление, эти ошибки формы теряются. Как я мог передать эти ошибки формы в сеансе, чтобы они отображались обратно в исходной форме (которая должна быть заполнена предыдущими данными, как в исходном поведении error_messages)?
Спасибо!
Код:
def create
@contact = Contact.new(params[:contact])
if @contact.save
flash[:notice] = "Sent."
else
flash[:notice] = "Error."
end
end
2 ответа
Это сложная проблема, с которой у меня были проблемы. Первый вопрос, который я хотел бы задать: зачем вам перенаправлять при обнаружении ошибок? Принудительное рендеринг действия при возникновении ошибок было сознательным решением разработчиков среды Rails из-за сложности и удобства использования.
Вот большая проблема, поэтому в вашем действии вы создаете экземпляр модели с использованием параметров, проверка объекта не проходит, и вы решаете перенаправить на другое действие. Перед перенаправлением на другое действие вам нужно сохранить текущее состояние экземпляра модели в сеансе, а затем перенаправить на action: foo. В действии: foo вам придется повторить попытку обновить атрибуты и передать ошибки представлению через переменную экземпляра. Проблема здесь в том, что вы связываете действия в своем контроллере, что плохо (одно действие зависит от другого). Есть множество других проблем, которые я мог бы напечатать навсегда, но если вам нужно сделать это только для одного ресурса, вот как я бы это сделал:
конфиг / routes.rb
map.resources :things, :member => { :create_with_errors => :get }
things_controller.rb
def new
@thing = Thing.new
end
def create
@thing = Thing.create(params[:thing])
if @thing.save
redirect_to things_path
else
session[:thing] = @thing
redirect_to create_errors_thing_path(@thing)
end
end
def create_with_errors
@thing = session[:thing]
@errors = @thing.errors
render :action => :new
end
приложение / просмотров / вещи / new.html.erb
<% if defined?(@errors) %>
<% #do something with @errors to display the errors %>
<% end %>
<!-- render the form stuff -->
Я знаю, о чем ты думаешь... это отвратительно. Поверьте мне, я сделал много попыток решить эту проблему, и я понял, что механизм, который выбрали разработчики рельсов, является лучшим и самым простым способом устранения ошибок.
Соглашение в Rails состоит в том, чтобы визуализировать исходное представление действия, а не делать перенаправление. Итак, ваш код будет выглядеть так:
def create
@contact = Contact.new(params[:contact])
if @contact.save
flash[:notice] = 'Sent.'
redirect_to @contact
else
flash.now[:notice] = 'Error.'
render :new
end
end
Если необходимо выполнить какие-либо дополнительные настройки для new
действие, извлеките общий код в приватный метод и вызовите его в before_filter
для обоих new
а также create
,