Rails нет ошибки маршрута, в то время как rake routes выдает маршрут

#ruby-on-rails #resources #routes #nested

#ruby-on-rails #Ресурсы #маршруты #вложенный

Вопрос:

Я имею дело с вложенной «фермой» ресурсов в Rails, и моя форма для создания новой фермы выглядит следующим образом:

  <%= form_for([@user, @farm], :url=> new_user_farm_path(@user)) do |f| %>
 <% if @farm.errors.any? %>
 <div id="error_explanation">
  <h2><%= pluralize(@farm.errors.count, "error") %> prohibited this farm from being saved:</h2>

  <ul>
  <% @farm.errors.full_messages.each do |msg| %>
    <li><%= msg %></li>
  <% end %>
  </ul>
  </div>
  <% end %>

  <div class="field">
  <%= f.label :name %><br />
  <%= f.text_field :name %>
  </div>
  <div class="field">
  <%= f.label :contact %><br />
  <%= f.text_field :contact %>
  </div>
  <div class="field">
  <%= f.label :adress %><br />
  <%= f.text_field :adress %>
  </div>
  <div class="actions">
  <%= f.submit %>
  </div>
  <% end %>
  

Моя соответствующая «новая» функция в контроллере farms является:

  def new
  @farm = Farm.new
  @user = User.find(current_user)


   respond_to do |format|
   format.html # new.html.erb
   format.json { render json: @farm }
end
end
  

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

  No route matches [POST] "/users/2/farm/new"
  

В моих rake routes у меня четко отображается маршрут:

      user_farm POST   /users/:user_id/farm(.:format) {:action=
    create", :controller=>"farms"}
  

Я только предполагаю, что проблема в моей функции create:

  def create
@farm = Farm.new(params[:farm])
@user = User.find(current_user)


respond_to do |format|
  if @farm.save
    format.html { redirect_to user_farm(@user, @farm), notice: 'Farm was successfully created.' }
    format.json { render json: @farm, status: :created, location: @farm }
  else
    format.html { render action: "new" }
    format.json { render json: @farm.errors, status: :unprocessable_entity }
  end
end
end    
  

Мой файл routes.rb:

   resources :users do
  resource :farm
  end


  devise_for :users, :path => 'accounts'
  

Я получаю доступ к своей новой форме фермы по этой ссылке:

  <%= link_to "New Farm", new_user_farm_path(current_user) %>
  

Все мои rake routes:

            user_farm POST   /users/:user_id/farm(.:format)       {:action=>"
           create", :controller=>"farms"}
           new_user_farm GET    /users/:user_id/farm/new(.:format)   {:action=>"
           new", :controller=>"farms"}
           edit_user_farm GET    /users/:user_id/farm/edit(.:format)  {:action=>"
           edit", :controller=>"farms"}
                     GET    /users/:user_id/farm(.:format)       {:action=>"
           show", :controller=>"farms"}
                     PUT    /users/:user_id/farm(.:format)       {:action=>"
           update", :controller=>"farms"}
                     DELETE /users/:user_id/farm(.:format)       {:action=>"
           destroy", :controller=>"farms"}
               users GET    /users(.:format)                     {:action=>"
           index", :controller=>"users"}
                     POST   /users(.:format)                     {:action=>"
           create", :controller=>"users"}
            new_user GET    /users/new(.:format)                 {:action=>"
           new", :controller=>"users"}
           edit_user GET    /users/:id/edit(.:format)            {:action=>"
           edit", :controller=>"users"}
                user GET    /users/:id(.:format)                 {:action=>"
           show", :controller=>"users"}
                     PUT    /users/:id(.:format)                 {:action=>"
           update", :controller=>"users"}
                     DELETE /users/:id(.:format)                 {:action=>"
           destroy", :controller=>"users"}
           new_user_session GET    /accounts/sign_in(.:format)          {:action=>"
           new", :controller=>"devise/sessions"}
           user_session POST   /accounts/sign_in(.:format)          {:action=>"
           create", :controller=>"devise/sessions"}
           destroy_user_session GET    /accounts/sign_out(.:format)         {:action=>"
           destroy", :controller=>"devise/sessions"}
           user_password POST   /accounts/password(.:format)         {:action=>"
           create", :controller=>"devise/passwords"}
           new_user_password GET    /accounts/password/new(.:format)     {:action=>"
           new", :controller=>"devise/passwords"}
           edit_user_password GET    /accounts/password/edit(.:format)    {:action=>"
           edit", :controller=>"devise/passwords"}
                     PUT    /accounts/password(.:format)         {:action=>"
           update", :controller=>"devise/passwords"}
           cancel_user_registration GET    /accounts/cancel(.:format)            {:action=>"
           cancel", :controller=>"devise/registrations"}
           user_registration POST   /accounts(.:format)                  {:action=>"
           create", :controller=>"devise/registrations"}
           new_user_registration GET    /accounts/sign_up(.:format)           {:action=>"
           new", :controller=>"devise/registrations"}
           edit_user_registration GET    /accounts/edit(.:format)             {:action=>"
           edit", :controller=>"devise/registrations"}
                     PUT    /accounts(.:format)                  {:action=>"
           update", :controller=>"devise/registrations"}
                     DELETE /accounts(.:format)                  {:action=>"
           destroy", :controller=>"devise/registrations"}
           user_confirmation POST   /accounts/confirmation(.:format)     {:action=>"
           create", :controller=>"devise/confirmations"}
           new_user_confirmation GET    /accounts/confirmation/new(.:format) {:action=>"
           new", :controller=>"devise/confirmations"}
                     GET    /accounts/confirmation(.:format)     {:action=>"
           show", :controller=>"devise/confirmations"}
           user_unlock POST   /accounts/unlock(.:format)           {:action=>"
           create", :controller=>"devise/unlocks"}
           new_user_unlock GET    /accounts/unlock/new(.:format)       {:action=>"
           new", :controller=>"devise/unlocks"}
                     GET    /accounts/unlock(.:format)           {:action=>"
           show", :controller=>"devise/unlocks"}
           home_index GET    /home/index(.:format)                {:controlle
           r=>"home", :action=>"index"}
                root        /                                    {:controlle
           r=>"home", :action=>"index"}
  

Ответ №1:

Проблема в том, что ваша форма пытается отправить запрос POST на URL, который существует только для запросов GET. Итак, это говорит вам о том, что

 [POST] "/users/2/farm/new"
  

не существует — чего на самом деле нет. И ваш rake routes вывод подтверждает это — проблема в том, что

 new_user_farm GET    /users/:user_id/farm/new(.:format)
  

что является запросом GET.

Формы по умолчанию используют POST для создания новой записи, поэтому вам необходимо указать URL-адрес, на который можно отправить. Или вы можете позволить Rails вычислить это по состоянию ваших объектов. Так что либо

 <%= form_for([@user, @farm], :url=> user_farm_path(@user)) do |f| %>
  

или

 <%= form_for([@user, @farm]) do |f| %>
  

должно сработать. В первом случае мы используем именованный маршрут, который совпадает с маршрутом POST из вашего rake routes вывода. В последнем случае мы позволяем rails вычислять это на основе состояния вашего @farm объекта. То есть, если @farm is a new_record? , он отправит запрос POST на /users/:user_id/farm , или если @farm есть persisted? , то он отправит запрос PUT на /users/:user_id/farm . (Тот же путь, просто другой тип запроса.)

Комментарии:

1. Да, это была проблема. Извините, просто еще один вопрос, поскольку я новичок. Почему он не показывает мне ферму, которую я только что создал. В нем говорится: не удалось найти ферму без идентификатора. Я сильно подозреваю, что моя функция create каким-то образом не работает. Не могли бы вы, пожалуйста, проверить это и убедиться, что все в порядке?

2. @farm = Farm.new(params[:farm]) выглядит правильно … можете ли вы включить отладчик в свое действие create и проверить результат? Я не уверен, почему он запрашивает о поиске фермы, когда вы хотите ее создать. Возможно, вы выполняете неправильное действие? Кроме того, если у вас уже есть, current_user тогда вам вообще не нужно делать @user = User.find(current_user) бит — просто используйте current_user .

3. Я изменил это в своей create farm, но я по-прежнему получаю ту же ошибку. Он перенаправляет меня по этой ссылке: localhost: 3000/users/ 2/farm.11 . Я предполагаю, что мой redirect_to в моей функции create тоже не подходит.

4. О, хорошо. Поэтому примите к сведению мои правки в моем комментарии выше… Я на секунду растерялся. Так что да, redirect_to в вашем действии create должно быть user_farm_path(@user, @farm) не просто user_farm(@user, @farm) .

5. Более того, как сказал @Rich Peck, похоже, что вы хотите resources :farms в своем файле routes, а не только resource :farm .

Ответ №2:

Некоторые проблемы:

Параметры

При создании нового объекта ActiveRecord в Rails вам захочется использовать strong params :

 #app/controllers/farms_controller.rb
Class FarmsController < ApplicationController
   def new
      @farm = Farm.new
   end

   def create
      @farm = Farm.new(farm_params)
   end

   private

   def farm_params
      params.require(:farm).permit(:params, :for, :farm)
   end
end
  

Маршруты

Вы используете вложенную маршрутизацию, что может быть непросто, если вы к этому не привыкли.

Если вы еще этого не сделали, вам следует сделать это со своими маршрутами:

 #config/routes.rb
resources :users do
   resources :farm #-> /users/3/farm/new
end
  

Это даст вам возможность достичь этого маршрута либо из вашего контроллера, либо из представлений.
Если вы дадите мне дополнительную информацию (файл Routes), я смогу помочь в дальнейшем!

Публикация

Еще раз просмотрев проблему, кажется, я допустил оплошность раньше!!!

Как указано pdbobb , ошибка, безусловно, говорит о том, что вы пытаетесь достичь /new с помощью POST глагола. Это неверно, поскольку в соответствии с соглашениями Rails о маршрутизации ресурсов вам необходимо

введите описание изображения здесь

Вы сможете использовать ответ pdobb , но что более важно, нам нужно установить, почему ваша форма пытается отправить в new post.

Проблема, скорее всего, в вашем nested ресурсе

Комментарии:

1. Я добавил еще кое-какую информацию, пожалуйста, скажите мне, если вам нужно что-нибудь еще.

2. Точно, форма отображается без проблем. Я заполняю эти три поля, нажимаю «Создать ферму», и это выдает мне эту ошибку.

3. Хм — это ссылается на определенную строку или что-то еще?

4. Ничего, он только говорит: Ошибка маршрутизации, а затем выдает эту ошибку. Это одна из причин, по которой это так запутанно. Я действительно не знаю, что еще попробовать. Кстати, я добавил ваше предложение для сильных параметров, спасибо вам за это. Я действительно надеюсь, что мы сможем это выяснить.

5. Я использовал ответ @pdobb, но теперь он не показывает ферму, как вы можете видеть в моем комментарии к его ответу.