ruby-on-railsrubypostmanruby-on-rails-5

Rails 5 Filter chain halted as :set_product rendered or redirected error when indexing all products


I'm running a Rails api-only app with a product model. I've created products on the backend with activeadmin. When using postman to view individual products with a corresponding product ID, it returns the json data fine but when I try to view all product at: api/v1/products

I get this error:

Started GET "/api/v1/products/" for ::1 at 2019-05-28 11:12:47 +0100 Processing by Api::V1::ProductsController#index as JSON Parameters: {"product"=>{}} Filter chain halted as :set_product rendered or redirected Completed 404 Not Found in 5ms (Views: 0.2ms | ActiveRecord: 4.9ms)

Here's my controller:

module Api
  module V1
    class ProductsController < Api::V1::ApiController
      # do not authenticate users before viewing product listing or individual products
      before_action :authenticate_user!, except: %i[index show]
      before_action :set_product, only: %i[index show]

      # GET /product
      def index
        product = Product.all.order('id')
        render json: { success: true, data: product }, status: :ok
      end

      # GET /products/:id
      def show
        @product = Product.find(params[:id])
        render json: { success: true, data: @products }, status: :ok
      end

      private

      def set_product
        @products = Product.find(params[:id])
        rescue StandardError => error
        render json: { success: false, error: error }, status: 404
      end

      def product_params
        params.require(:product).permit(:title, :release_date, :release_time, :description, :price, :brand)
      end

    end
  end
end

Here are my API views:

_product.json.jbuilder

json.id               product.id
json.title            product.title
json.description      product.description
json.release_date     product.release_date
json.release_time     product.release_time
json.price            product.price
json.brand            product.brand

index.json.jbuilder

json.array! @products, partial: 'products/product', as: :product

show.json.jbuilder

json.product do
  json.partial! 'product' 
end

routes

namespace :api do
    namespace :v1, defaults: { format: :json } do
      devise_scope :user do
        get :status, to: 'api#status'
        resource :user, only: %i[update show] do
          get :profile
        end
      end
      resources :products, only: [:index, :show]
    end
    
  end

Solution

  • convert

    module Api
      module V1
        class ProductsController < Api::V1::ApiController
          # do not authenticate users before viewing product listing or individual products
          before_action :authenticate_user!, except: %i[index show]
          before_action :set_product, only: %i[index show]
    
          # GET /product
          def index
            product = Product.all.order('id')
            render json: { success: true, data: product }, status: :ok
          end
    
          # GET /products/:id
          def show
            @product = Product.find(params[:id])
            render json: { success: true, data: @products }, status: :ok
          end
    
          private
    
          def set_product
            @products = Product.find(params[:id])
            rescue StandardError => error
            render json: { success: false, error: error }, status: 404
          end
    
          def product_params
            params.require(:product).permit(:title, :release_date, :release_time, :description, :price, :brand)
          end
    
        end
      end
    end
    

    to

    module Api
      module V1
        class ProductsController < Api::V1::ApiController
          # do not authenticate users before viewing product listing or individual products
          before_action :authenticate_user!, except: %i[index show]
          before_action :set_product, only: %i[show]
    
          # GET /product
          def index
            @products = Product.all.order('id')
            render json: { success: true, data: @products }, status: :ok
          end
    
          # GET /products/:id
          def show
            if @product.present?
              render json: { success: true, data: @product }, status: :ok
            else
               render json: { success: false }, status: :not_found
            end
    
          end
    
          private
    
          def set_product
            @product = Product.find(params[:id])
          end
    
          def product_params
            params.require(:product).permit(:title, :release_date, :release_time, :description, :price, :brand)
          end
    
        end
      end
    end