Ошибка NoMethodError для нового контроллера в Rails

#ruby-on-rails

#ruby-on-rails

Вопрос:

Cities#new controller показывает ошибку, связанную с cities_path, но у меня ее нет ни в одном файле, ни в CitiesController. Я проверил все файлы, попытался перезапустить сервер, но по-прежнему ничего.

 undefined method `cities_path' for #<#<Class:0x007f9e4c1cb348>:0x00000003836140>
Did you mean?  city_path
 

CitiesController

 class CitiesController < ApplicationController

    def index
        @cities = City.all
    end

    def show
        find_city
    end

    def new
        @city = City.new
    end

    def edit
        find_city
    end

    def update
        find_city

        if @city.save
            redirect_to city_path(@city)
        else
            render "edit"
        end
    end

    def create
        @city = City.new(city_params)

        if @city.save
            redirect_to index_path
        else
            render "new"
        end
    end

    private

    def find_city
        @city = City.find(params[:id])
    end

    def city_params
        params.require(:city).permit(:name, :icon_url)
    end

end
 

Маршруты

   get "/cities/new" =>  "cities#new", as: "new_city"
  post "/index" => "cities#create"
  get "/cities/:id" => "cities#show", as: "city"
  get "/cities/:id/edit" => "cities#edit", as: "edit_city"
  patch "/city/:id" => "cities#update"
 

Форма (ошибка возникает в первой строке)

 <%= form_for @city do |f| %>

    <% if @city.errors.any? %>
        <div class="errors">
            <ul>
                <% city.errors.full_messages.each do |msg| %>
                    <li><%= msg %></li>
                <% end %>
            </ul>
        </div>
    <% end %>

    <%= f.label "Name:" %>
    <%= f.text_field :name, class: "form-control" %>

    <%= f.label "Icon:" %>
    <%= f.text_field :icon_url, class: "form-control" %>

    <%= f.submit "Pošalji" %>

<% end %>
 

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

1. Мне очень непонятно, почему ваш маршрут создания справедлив /index , в то время как все остальное ограничено /cities . Ваш маршрут индекса городов действительно должен быть /cities , а не /index .

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

Ответ №1:

Когда вы используете form_for @city , и @city это новая запись, form_for попытается найти cities_path , чтобы ОПУБЛИКОВАТЬ новые атрибуты обратно.

Вы должны использовать resources :cities в своем файле routes для автоматического определения маршрутов и их имен. Если вы хотите определить ограниченный набор маршрутов, вы можете использовать :only или :except :

 resources :cities, only: %i(new create show edit update)
 

Если вы не используете resources , вам необходимо либо явно указать путь для вашего form_for вызова, либо указать маршрут с именем cities_path вручную:

 post "/index" => "cities#create", as: :cities
 

Обратите внимание, что индексные маршруты обычно на самом деле не содержат слова index , вы должны просто публиковать /cities , а не /index .

  post "/cities" => "cities#create", as: :cities