Я новичок в рельсах и не уверен, что согласен с тем, как я поступал в некоторых обучающих материалах, которые я прошел. Проблема связана с тем, как обрабатывать недопустимые отправленные формы. Стандартный способ работы выглядит следующим образом:
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), предыдущая отправка пользователя теряется, как и сообщения об ошибках.
Я понимаю, что RESTfully, этот метод может быть «правильным», поскольку создание объекта thing должно быть результатом POSTing в / things, но с точки зрения пользовательского интерфейса меня это особо не волнует.
Я мог бы «вручную» сохранить недопустимый объект @thing в сеансе пользователя, чтобы он отображался после того, как я перенаправлю его обратно на new_thing_path, но это похоже на взлом. Похоже, что для этого должен быть «рельсовый способ».
Идеи ?
2 ответа
Как вы обнаружили, по умолчанию, когда вы указываете 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
),
- URL изменится с
/things/new
на/things
- Нажатие назад предлагает повторно отправить форму
- Обновление шоу
things#index
Это не функциональность, которую я испытываю в моих собственных приложениях Rails 3. Вместо этого я обнаружил, что: после отправки нового thing
(отправка формы на /things/new
),
- URL изменится с
/things/new
на/things
(это то же самое) - При нажатии кнопки "назад" пользователь возвращается к не -отправленной форме (нет запроса на повторную публикацию)
- Обновление запросов на повторную отправку формы (как и ожидалось, на мой взгляд)
Я знаю, что это старый вопрос, но один подход, с которым я играл в последнее время, - это отправить форму с помощью AJAX, даже если в противном случае это не потребовалось бы. Это позволяет отправить его в действие по умолчанию для создания / обновления по всем маршрутам, но URL-адрес в браузере не изменяется. Ответ может быть простым 200 для успеха со ссылкой на страницу / index или куда вы перенаправляете при успешном сохранении, или «400 неверный запрос» с сообщением (ями) об ошибке, если данные были недопустимыми.
Самым большим недостатком является то, что отображение сообщений об ошибках и недопустимых полей теперь полностью зависит от JavaScript на стороне клиента. Это становится гораздо меньшей проблемой и даже может быть полезным, если вы используете что-то вроде Backbone или KnockoutJS на стороне клиента.
Похожие вопросы
Связанные вопросы
Новые вопросы
ruby-on-rails-3
Ruby on Rails - это фреймворк для веб-разработки с открытым исходным кодом, написанный на Ruby. Ruby on Rails следует принципу соглашения о конфигурации, освобождая вас от необходимости заново изобретать вещи, чтобы оставаться продуктивными. Используйте этот тег только для вопросов, касающихся Rails 3, а также пометьте эти вопросы [ruby-on-rails].