2017-01-02 4 views
7

Я использую Rails 5. У меня есть страница, на которой пользователь может обновлять свой профиль, и если что-то пойдет не так, они возвращаются на страницуКак предотвратить изменение URL-адреса в строке браузера, когда пользователь возвращается в форму для исправления ошибок?

def update 
    @user = current_user 
    if @user.update_attributes(user_params) 
     … 
     redirect_to url_for(:controller => ‘main’, :action => 'index') and return 
    end 

    render 'edit' 
    end 

Проблема заключается в том, когда они будут возвращены к оригиналу страницы, URL-адрес в строке браузера читает «http://localhost:3000/users/51», который не является исходным URL-адресом, который они посещали (это было «http://localhost:3000/users/edit»). Как я могу заставить URL-адрес оставаться таким же, как и он?

Edit: Это то, что получается, когда я бег рек маршрутов

  edit_users GET /users/edit(.:format)      users#edit 
       users GET /users(.:format)       users#index 
         POST /users(.:format)       users#create 
      new_user GET /users/new(.:format)      users#new 
      edit_user GET /users/:id/edit(.:format)     users#edit 
       user GET /users/:id(.:format)      users#show 
         PATCH /users/:id(.:format)      users#update 
         PUT /users/:id(.:format)      users#update 
         DELETE /users/:id(.:format)      users#destroy 
+0

'и return' - это плохая привычка, так как нет никакой гарантии, что такие вещи, как метод redirect_to, возвращают логически истинное значение. Гораздо лучше сделать 'return redirect_to ...', поэтому нет никаких шансов, что это не удастся. – tadman

+0

Обычно я рекомендую делать '@ user.update_attributes!' И перенаправлять. Если возникнет проблема с обновлением, вы получите ошибку «ActiveRecord :: RecordInvalid», которую вы можете спасти и обработать с помощью «render (action: 'edit')». – tadman

+0

Я не понимаю, на какой ответ я прочитал ваши комментарии. Выполнение явно переходит к строке «render» edit », потому что в модели есть ошибка, но URL-адрес на результирующей странице не совпадает с предыдущим. –

ответ

2

вы можете использовать следующий синтаксис:

redirect_to :back 
+0

Это не работает. Хотя URL-адрес один и тот же, любые сообщения об ошибках, которые были привязаны к модели, не отображаются в представлении, как раньше, когда я имел «визуализацию». –

1

Я подозреваю, что это может быть то, что вы ищете.

redirect_to :edit 

http://api.rubyonrails.org/classes/ActionController/Redirecting.html

+0

Хотя я добавил «redirect_to: edit», это привело к ошибке «undefined method' edit_url »для # Вы имели в виду? Edit_user_url". Кроме того, вы уверены, что ваше решение не будет страдать от той же проблемы, что и решение djothefou? –

4

Я считаю, что ваше предположение не является правильным. Вы спрашиваете Как предотвратить изменение URL-адреса в строке браузера, когда пользователь возвращается в форму для исправления ошибок?

И ответ: URL-адрес браузера не изменяется, когда пользователь снова видит форму для исправления ошибок. Поскольку URL-адрес уже был изменен, когда форма была отправлена ​​в первый раз.

С помощью routes.rb следующих общих конвенций ваш будет иметь следующие маршруты (используйте rails routes перечислить их): обновление формы

GET /users(.:format)   users#index 
POST /users(.:format)   users#create 
GET /users/new(.:format)  users#new 
GET /users/:id/edit(.:format) users#edit 
GET /users/:id(.:format)  users#show 
PATCH /users/:id(.:format)  users#update 
PUT /users/:id(.:format)  users#update 
DELETE /users/:id(.:format)  users#destroy 

Пользователь визуализируется, когда вы делаете GET запрос /users/:id/edit. Но фактический запрос на обновление из этой формы отправляется на PATCH /users/:id. Это означает, что браузер использует уже другой URL-адрес.

В методе update (помните, что это уже в URL /users/:id) Вы в основном есть только два варианта:

  1. рендера что-то. Рендеринг представления в действии сохраняет URL одинаковым (он все равно будет /users/:id), но у вас есть изменение на использование пользователя, назначенного для @user, например, чтобы показать его ошибки в форме. Это поведение по умолчанию Rails при сбое обновления.
  2. Вы можете перенаправить браузер на другой URL (например, обратно на /users/:id/edit или на совершенно другой URL-адрес, например на домашнюю страницу). Это изменяет URL-адрес в адресной строке браузера. Но перенаправление всегда делает новый запрос GET, что означает, что вы теряете информацию, отправляемую через post, и вы потеряете экземпляр User, назначенный в настоящее время для @user. После GET пользователь перезагружается из базы данных и поэтому не имеет назначенных ошибок. В Rails перенаправление используется, когда обновление было успешным, чтобы предотвратить другой POST, если пользователь нажимает кнопку перезагрузки в браузере.

IMHO Ответ на ваш вопрос: вы не можете делать то, что хотите, не покидая путь, выбранный Rails, и создаете совершенно другой маршрут, контроллер и форму. Вам нужно будет настроить маршрут, который будет одинаковым для запросов GET и PATCH (или POST). И метод контроллера должен иметь возможность обрабатывать оба типа запросов по-разному. Поскольку маршрутизация ресурсов Rails 2.0 является предпочтительным способом. То, что вы хотите, было распространено до Rails 2.0

Мой совет: Следуйте соглашениям Rails. URL-адрес не важен, никто не заботится. Я не вижу преимуществ в том, чтобы не следовать правилам Rails только для того, чтобы иметь другой URL для формы.

+1

Поскольку я новичок в Rails, я не совсем понимаю, что такое ответ, хотя я редактировал свой вопрос, чтобы включить мои «рейк-маршруты». Что касается «URL-адреса не важны, никто действительно не заботится», мне все равно, и именно поэтому я задал вопрос. Если вы чувствуете, что это глупо или глупо, не стесняйтесь плакать/понижать меня или просто не отвечать, но мой вопрос остается. –

1

Я боролся с тем же, когда начал использовать рельсы.

Однако ...

Одна вещь, чтобы иметь ум, почему Rails называется "Rails."

Рельсы называются рельсами, потому что основной принцип проектирования Rails - это железная дорога. Rails упрощает создание веб-сайта, одобряя соглашение по конфигурации, и это означает, что вы предлагаете один и только один способ сделать что-то, отсюда аналогия железной дороги.

Мы, как программисты, когда решили использовать Rails, мы соглашаемся придерживаться железнодорожных путей, которые Rails создали для нас в обмен на легкий опыт программирования. Это точно так же, как выбрать поезд над автомобилем, вы должны оставаться на ходу, но взамен все становится проще.

Следовательно, ответ каждого человека, скорее всего, будет выглядеть так: «Не беспокойтесь о том, чтобы идти в отрыв, просто следуйте по железнодорожным путям».

Вы можете прочитать больше о «Конвенции по конфигурации» и философии дизайна Rails в этой статье DHH, который является создателем Rails - http://rubyonrails.org/doctrine

0

Даже если это не рекомендуется, можно делать то, что вы хочу:

  • Использование render для отображения ошибок
  • Создать маршрут PUT или PATCH с URL /users/edit в routes.rb
  • использовать этот маршрут, по вашему мнению (с щеколда form_for параметры)
  • Хранить идентификатор пользователя где:
    • при редактировании зарегистрированного пользователя, я бы рекомендовал использовать сессии.
    • в противном случае я бы рекомендовал добавить hidden_field_tag параметр в виде
  • Обновление current_user функции в контроллере соответственно
0

Используйте этот

redirect_to edit_user_path 
+1

Еще лучше, 'redirect_to edit_user_path (current_user)' поэтому Rails будет знать, какой пользователь – Jaeger

0

Держите show и edit тем же шаблоном, который будет работать для обеих целей, он фактически редактирует страницу при редактировании, иначе обрабатывается как страница показа, при наличии ошибок в нем будут отображаться ошибки

Смежные вопросы