Форма отправляет меня на неправильный контроллер, несмотря на правильный URL-адрес в приложении Rails

У меня определены следующие маршруты:

Приложение/config/routes.rb

resources :pools do
  resources :match_predictions, path: "predictions", as: "predictions", only:[:index, :create, :update]
  post "predictions/season" => "season_predictions#create"
  patch "predictions/season" => "season_predictions#update"
  put "predictions/season" => "season_predictions#update
end

В результате получаются следующие paths/Url/controller#action (для простоты опуская маршруты ресурсов пула):

          pool_predictions GET    /pools/:pool_id/predictions(.:format)                                                    match_predictions#index
                           POST   /pools/:pool_id/predictions(.:format)                                                    match_predictions#create
           pool_prediction PATCH  /pools/:pool_id/predictions/:id(.:format)                                                match_predictions#update
                           PUT    /pools/:pool_id/predictions/:id(.:format)                                                match_predictions#update
   pool_predictions_season POST   /pools/:pool_id/predictions/season(.:format)                                             season_predictions#create
                           PATCH  /pools/:pool_id/predictions/season(.:format)                                             season_predictions#update
                           PUT    /pools/:pool_id/predictions/season(.:format)                                             season_predictions#update

В качестве контекста: у меня есть три модели: Pool, MatchPrediction, SeasonPrediction. Каждый @pool – это спортивное соревнование, в котором есть_много @match_prediction и есть_один @season_prediction. Ключевым представлением в моем приложении является место, где пользователь публикует/обновляет свои прогнозы. Поскольку в основном это @match_predictions, я использую match_predictions#index и match_predictions/index.html.erb для управления/отображения этого представления. Доступ к этому представлению осуществляется через:

/pool/:pool_id/predictions

Проблема: у меня есть форма для создания/обновления @season_prediction, которая находится в сфере ресурса match_predictions. Чтобы сохранить сообщения об ошибках, в случае сбоя сохранения объектов я визуализирую match_predictions/index.html.erb после сбоя действий обновления/создания в Season_predictions_controller. Это хорошо работает с маршрутами по умолчанию, скажем, если я это сделаю:

resources :pools do
  resources :match_predictions, path: "predictions", as: "predictions", only:[:index, :create, :update]
  resources :season_predictions
end

Однако это имеет непреднамеренное последствие изменения пути к местоположению на что-то вроде:

/pool/:pool_id/season_predictions/:id

Я думаю, что это может сбить пользователя с толку, поскольку он все еще находится в том же представлении, в то время как URL-адрес резко изменился. Кроме того, :id в конце URL-адреса не имеет никакого смысла, поскольку пользователь может иметь только один прогноз сезона для каждого пула. Следовательно, с помощью этого подхода я хотел достичь

  1. URL-адрес после неудачного действия должен быть максимально похож на исходный /pool/:pool_id/match_predictions.
  2. Удалите :id в конце URL-адреса, принадлежащего @season_prediction.
  3. Используйте ту же форму для создания или обновления @season_prediction в зависимости от того, обслуживаю ли я новый экземпляр или ранее сохраненный экземпляр из контроллера.

Пока у меня есть такая форма:

<%= simple_form_for([@pool, @season_prediction], url: pool_predictions_season_path) do |f| %>
  <div class="form-inputs">
    <%= f.input :champion %>
    <%= f.input :second_place %>
    <%= f.input :third_place %>
    <%= f.input :last_place %>
    <%= f.association :pool_participant %>
  </div>
  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

Хотя визуализированная HTML-форма устанавливает правильный путь действия: action="/pools/1/predictions/season" при отправке она отправляет запрос на match_predictions#update, что я не понимаю, почему именно, поскольку этот контроллер не участвует.

Не могли бы вы помочь мне понять, почему и достичь ожидаемого результата?


person alopez02    schedule 28.03.2018    source источник


Ответы (1)


Таким образом, кажется, что при установке маршрутов с косой чертой, например, между «прогнозами» и «сезонами» в следующих маршрутах:

  post "predictions/season" => "season_predictions#create"
  patch "predictions/season" => "season_predictions#update"
  put "predictions/season" => "season_predictions#update

Это мешало Rails таким образом, что контроллер Season_Prediction игнорировался, а контроллер match_predictions был достигнут с учетом настройки метода URL-адреса as: "predictions", которые целенаправленно совпадают.

resources :match_predictions, path: "predictions", as: "predictions", only:[:index, :create, :update]

В итоге я избавился от косой черты и установил маршруты Season_Prediction, как показано ниже:

put "predictionss" => "season_predictions#update"

Да, с двойным 's' в конце, чтобы отличать маршруты контроллера прогнозов матчей. Это совсем не похоже на лучшую практику. Это может сбить с толку других людей при чтении кода, но, по крайней мере, пользователь вряд ли заметит изменение.

person alopez02    schedule 29.03.2018