Как передать ошибки формы в сессию или флэш? [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,

Другие вопросы по тегам