Маршрутизация Rails, не предоставляющая индекс и использующая его как отображение для вложенных ресурсов

#ruby-on-rails

#ruby-on-rails

Вопрос:

У меня был этот учебник, работающий для другого упражнения, но теперь я применяю фактическую работу на практике и не могу понять, что я сейчас делаю неправильно.
https://www.digitalocean.com/community/tutorials/how-to-create-nested-resources-for-a-ruby-on-rails-application

Вот моя модель категорий продуктов

 class ProductCategory < ApplicationRecord
    has_many :products
end
 

моя модель продукта:

 class Product < ApplicationRecord
  belongs_to :product_category
end
 

Мои маршруты.rb:

 Rails.application.routes.draw do
  root 'product_categories#index'
  resources :product_categories do
    resource :products
  end
end
 

Фактический вывод маршрутов для маршрутов rails:

 % rails routes
                                  Prefix Verb   URI Pattern                                                                                       Controller#Action
                                    root GET    /                                                                                                 product_categories#index
           new_product_category_products GET    /product_categories/:product_category_id/products/new(.:format)                                   products#new
          edit_product_category_products GET    /product_categories/:product_category_id/products/edit(.:format)                                  products#edit
               product_category_products GET    /product_categories/:product_category_id/products(.:format)                                       products#show
                                         PATCH  /product_categories/:product_category_id/products(.:format)                                       products#update
                                         PUT    /product_categories/:product_category_id/products(.:format)                                       products#update
                                         DELETE /product_categories/:product_category_id/products(.:format)                                       products#destroy
                                         POST   /product_categories/:product_category_id/products(.:format)                                       products#create
                      product_categories GET    /product_categories(.:format)                                                                     product_categories#index
                                         POST   /product_categories(.:format)                                                                     product_categories#create
                    new_product_category GET    /product_categories/new(.:format)                                                                 product_categories#new
                   edit_product_category GET    /product_categories/:id/edit(.:format)                                                            product_categories#edit
                        product_category GET    /product_categories/:id(.:format)                                                                 product_categories#show
                                         PATCH  /product_categories/:id(.:format)                                                                 product_categories#update
                                         PUT    /product_categories/:id(.:format)                                                                 product_categories#update
                                         DELETE /product_categories/:id(.:format)                                                                 product_categories#destroy
           rails_postmark_inbound_emails POST   /rails/action_mailbox/postmark/inbound_emails(.:format)                                           action_mailbox/ingresses/postmark/inbound_emails#create
              rails_relay_inbound_emails POST   /rails/action_mailbox/relay/inbound_emails(.:format)                                              action_mailbox/ingresses/relay/inbound_emails#create
           rails_sendgrid_inbound_emails POST   /rails/action_mailbox/sendgrid/inbound_emails(.:format)                                           action_mailbox/ingresses/sendgrid/inbound_emails#create
     rails_mandrill_inbound_health_check GET    /rails/action_mailbox/mandrill/inbound_emails(.:format)                                           action_mailbox/ingresses/mandrill/inbound_emails#health_check
           rails_mandrill_inbound_emails POST   /rails/action_mailbox/mandrill/inbound_emails(.:format)                                           action_mailbox/ingresses/mandrill/inbound_emails#create
            rails_mailgun_inbound_emails POST   /rails/action_mailbox/mailgun/inbound_emails/mime(.:format)                                       action_mailbox/ingresses/mailgun/inbound_emails#create
          rails_conductor_inbound_emails GET    /rails/conductor/action_mailbox/inbound_emails(.:format)                                          rails/conductor/action_mailbox/inbound_emails#index
                                         POST   /rails/conductor/action_mailbox/inbound_emails(.:format)                                          rails/conductor/action_mailbox/inbound_emails#create
       new_rails_conductor_inbound_email GET    /rails/conductor/action_mailbox/inbound_emails/new(.:format)                                      rails/conductor/action_mailbox/inbound_emails#new
      edit_rails_conductor_inbound_email GET    /rails/conductor/action_mailbox/inbound_emails/:id/edit(.:format)                                 rails/conductor/action_mailbox/inbound_emails#edit
           rails_conductor_inbound_email GET    /rails/conductor/action_mailbox/inbound_emails/:id(.:format)                                      rails/conductor/action_mailbox/inbound_emails#show
                                         PATCH  /rails/conductor/action_mailbox/inbound_emails/:id(.:format)                                      rails/conductor/action_mailbox/inbound_emails#update
                                         PUT    /rails/conductor/action_mailbox/inbound_emails/:id(.:format)                                      rails/conductor/action_mailbox/inbound_emails#update
                                         DELETE /rails/conductor/action_mailbox/inbound_emails/:id(.:format)                                      rails/conductor/action_mailbox/inbound_emails#destroy
new_rails_conductor_inbound_email_source GET    /rails/conductor/action_mailbox/inbound_emails/sources/new(.:format)                              rails/conductor/action_mailbox/inbound_emails/sources#new
   rails_conductor_inbound_email_sources POST   /rails/conductor/action_mailbox/inbound_emails/sources(.:format)                                  rails/conductor/action_mailbox/inbound_emails/sources#create
   rails_conductor_inbound_email_reroute POST   /rails/conductor/action_mailbox/:inbound_email_id/reroute(.:format)                               rails/conductor/action_mailbox/reroutes#create
                      rails_service_blob GET    /rails/active_storage/blobs/redirect/:signed_id/*filename(.:format)                               active_storage/blobs/redirect#show
                rails_service_blob_proxy GET    /rails/active_storage/blobs/proxy/:signed_id/*filename(.:format)                                  active_storage/blobs/proxy#show
                                         GET    /rails/active_storage/blobs/:signed_id/*filename(.:format)                                        active_storage/blobs/redirect#show
               rails_blob_representation GET    /rails/active_storage/representations/redirect/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations/redirect#show
         rails_blob_representation_proxy GET    /rails/active_storage/representations/proxy/:signed_blob_id/:variation_key/*filename(.:format)    active_storage/representations/proxy#show
                                         GET    /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format)          active_storage/representations/redirect#show
                      rails_disk_service GET    /rails/active_storage/disk/:encoded_key/*filename(.:format)                                       active_storage/disk#show
               update_rails_disk_service PUT    /rails/active_storage/disk/:encoded_token(.:format)                                               active_storage/disk#update
                    rails_direct_uploads POST   /rails/active_storage/direct_uploads(.:format)                                                    active_storage/direct_uploads#create
 

ProductCategoriesController:

 class ProductCategoriesController < ApplicationController
    before_action :set_product_category, except: [:index, :new, :create]

    def index
        @categories = ProductCategory.all
    end

    def show
    end

    def new
        @category = ProductCategory.new
    end

    def create
        @category = ProductCategory.new(category_params)

        respond_to do |format|
            if @category.save
                format.html { redirect_to root_path }
            else
                format.html { render :edit, status: :unprocessable_entity }
            end
        end
    end

    private
        def set_product_category
            @product_category = ProductCategory.find(params[:id])
            @name = @product_category.name
        end

        def category_params
            params.require(:product_category).permit(:name)
        end


end
 

и, наконец, ProductsController:

 class ProductsController < ApplicationController
    before_action :get_product_category
    before_action :set_product, except: [:index, :new, :create]

    def index
        @products = @product_category.products
    end

    def show
    end

    def new
        @product = @product_category.products.build
    end

    def edit
    end

    def create
        @product = @product_category.products.build(product_params)

        respond_to do |format|
            if @product.save
                format.html { redirect_to product_category_products_path(@product_category), notice: "Product was successfully created." }
                format.json { render :show, status: :created, location: @product }
            else
                format.html { render :new, status: :unprocessable_entity }
                format.json { render json: @product.errors, status: :unprocessable_entity }
            end
        end
    end

    def update
        respond_to do |format|
            if @product.update(product_params)
                format.html { redirect_to @product, notice: "Product was successfully updated." }
                format.json { render :show, status: :ok, location: @product }
            else
                format.html { render :edit, status: :unprocessable_entity }
                format.json { render json: @product.errors, status: :unprocessable_entity }
            end
        end
    end

    def destroy
        @product.destroy
        respond_to do |format|
            format.html { redirect_to products_url, notice: "Product was successfully destroyed." }
            format.json { head :no_content }
        end
    end
    

    private
        def get_product_category
            @product_category = ProductCategory.find(params[:product_category_id])
        end

        def set_product
            @product = @product_category.products.find(params[:id])
            
        end

        def product_params
            params.require(:product).permit(:name, :description, :product_type)
        end
end
 

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

Любая помощь будет оценена. Спасибо.

Ответ №1:

У вас есть опечатка в вашем файле маршрутов:

     resource :products
 

должно быть

     resources :products
 

(Обратите внимание на пропущенные «s».) Как только вы исправите это, вы должны увидеть, что правильные маршруты генерируются Rails, и все работает так, как вы ожидаете.

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

1. Спасибо! трудно обнаружить эти опечатки, и у меня было ощущение, что это где-то было . , , поэтому я разместил здесь еще один набор глаз.

2. Нет проблем. Если бы это действительно было проблемой, было бы здорово, если бы вы могли пометить ответ как принятый.