Правильный способ обработки неверных представлений формы в Rails - PullRequest
9 голосов
/ 19 февраля 2011

Я новичок в рельсах и не уверен, что согласен с тем, как я справляюсь с некоторыми уроками, через которые я прошел.Проблема связана с тем, как обрабатывать неверные представления формы.Стандартный способ работы выглядит следующим образом:

class ThingsController < ApplicationController


  # POST /things
  def create

    @thing = Thing.new(params[:thing])

    if @thing.save
      flash[:notice] = 'Thing created'
      redirect_to(@thing)
    else
      render :action => :new
    end

  end

Когда происходит сбой @ thing.save, пользователю предоставляется та же форма, предварительно заполненная только что введенными значениями, а также миганиечто пошло не так.Пока все хорошо, за исключением того, что теперь URL-адрес изменился с / things / new на things /, что вместо этого можно было бы ожидать, что вместо этого будет отображаться представление индекса.

Кроме того, если пользователь обновляет страницу, он теперь просматривает индексное представление.Если он щелкает назад, ему предлагается повторно отправить форму, которую я всегда старался избегать.Если я redirect_to (new_thing_path), предыдущее представление пользователя теряется, как и сообщения об ошибках.

Я понимаю, что RESTful, этот метод может быть "правильным", так как создание объекта вещи должно быть результатом POSTing к / вещам, но с точки зрения пользовательского интерфейса, мне это не особо важно,

Я мог бы "вручную" сохранить недопустимый объект @thing в сеансе пользователя, чтобы он отображался после того, как я перенаправил его обратно на new_thing_path, но это похоже на хак.Кажется, должен быть "рельсовый способ" сделать это.

Идеи?

Ответы [ 2 ]

3 голосов
/ 20 февраля 2011

Как вы обнаружили, по умолчанию, когда вы указываете resources :things, путь POST для создания новой вещи находится в /things.Вот вывод для rake routes:

    things GET    /things(.:format)          {:action=>"index", :controller=>"things"}
           POST   /things(.:format)          {:action=>"create", :controller=>"things"}
 new_thing GET    /things/new(.:format)      {:action=>"new", :controller=>"things"}
edit_thing GET    /things/:id/edit(.:format) {:action=>"edit", :controller=>"things"}
     thing GET    /things/:id(.:format)      {:action=>"show", :controller=>"things"}
           PUT    /things/:id(.:format)      {:action=>"update", :controller=>"things"}
           DELETE /things/:id(.:format)      {:action=>"destroy", :controller=>"things"}

Звучит так, как будто вы хотите что-то похожее на это:

create_things POST   /things/new(.:format)      {:action=>"create", :controller=>"things"}
       things GET    /things(.:format)          {:action=>"index", :controller=>"things"}
    new_thing GET    /things/new(.:format)      {:action=>"new", :controller=>"things"}
   edit_thing GET    /things/:id/edit(.:format) {:action=>"edit", :controller=>"things"}
        thing GET    /things/:id(.:format)      {:action=>"show", :controller=>"things"}
              PUT    /things/:id(.:format)      {:action=>"update", :controller=>"things"}
              DELETE /things/:id(.:format)      {:action=>"destroy", :controller=>"things"}

Хотя это и не рекомендуется, вы можете получить этот результат по следующему маршруту:

resources :things, :except => [ :create ] do
  post "create" => "things#create", :as => :create, :path => 'new', :on => :collection
end

Вам также понадобится изменить свои формы, чтобы сделать их POST по правильному пути.

При всем этом, описание URL-адресов, которые у вас есть в вашем вопросе, незвучит правильно.Вы перечисляете следующее: После отправки нового thing (отправки формы на /things/new),

  1. URL-адрес изменится с /things/new на /things
  2. Нажатие на кнопкупредлагает повторить отправку формы
  3. Обновление шоу things#index

Это , а не функциональность, которую я испытываю в своих собственных приложениях на Rails 3.Вместо этого я обнаружил, что: после отправки нового thing (отправка формы на /things/new),

  1. URL-адрес изменится с /things/new на /things (это то же самое)
  2. Нажатие на кнопку возвращает пользователя к отправленной не форме (нет запроса на повторную публикацию)
  3. Обновление подсказок для повторной отправки формы (как и ожидалось, на мой взгляд))
0 голосов
/ 03 июня 2014

Я знаю, что это старый вопрос, но один из подходов, с которым я в последнее время играл, - это отправить форму с помощью AJAX, даже если в противном случае она не потребовалась бы.Это позволяет отправить его в действие по умолчанию для создания / обновления маршрутов, но URL-адрес в браузере не изменяется.Ответом может быть простое 200 для успеха со ссылкой на страницу / index или куда бы вы ни перенаправили при успешном сохранении, или «400 неверных запросов» с сообщениями об ошибках, если данные были неверными.

Самым большим недостатком является то, что отображение сообщений об ошибках и недействительных полей теперь полностью лежит на вашем клиентском JavaScript.Это становится намного меньшей проблемой и может даже оказаться полезным, если вы используете что-то вроде Backbone или KnockoutJS на стороне клиента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...