bploetz / versionist

A plugin for versioning Rails based RESTful APIs.
MIT License
972 stars 51 forks source link

#<NoMethodError: undefined method `api_version' for #<ActionDispatch::Routing::Mapper:0x00007f9d48808e40 #94

Open Vicente-jpro opened 2 years ago

Vicente-jpro commented 2 years ago

I am trying to call my api but the method api_version. Do not work! Is there any additional code to past in may rails app?

controllerV2

module V2
  class ContactsController < ApplicationController
    before_action :set_contact, only: %i[ show update destroy ]

    # GET /contacts
    def index
      @contacts = Contact.last(3)

      render json: @contacts
    end

    # GET /contacts/1
    def show
      #render json: { contact:  @contact.in_portuguese, message: "Success." }
      render json: @contact, include: [:kind, :address, :phone]
    end

    # POST /contacts
    def create
      @contact = Contact.new(contact_params)

      if @contact.save
        render json: @contact, status: :created, location: @contact
      else
        render json: @contact.errors, status: :unprocessable_entity
      end
    end

    # PATCH/PUT /contacts/1
    def update
      if @contact.update(contact_params)
        render json: @contact
      else
        render json: @contact.errors, status: :unprocessable_entity
      end
    end

    # DELETE /contacts/1
    def destroy
      @contact.destroy
    end

    private
      # Use callbacks to share common setup or constraints between actions.
      def set_contact
        @contact = Contact.find(params[:id])
      end

      # Only allow a list of trusted parameters through.
      def contact_params
         # params.require(:contact).permit(
         #   :name, :email, :birthdate, :kind_id, 
         #   phones_attributes: [:id, :number],
         #   address_attributes: [:id, :city, :street ]
         # )

        ActiveModelSerializers::Deserialization.jsonapi_parse(params)
      end
  end
end

ControlerV1

module V1
  class ContactsController < ApplicationController
    before_action :set_contact, only: %i[ show update destroy ]

    # GET /contacts
    def index
      @contacts = Contact.all

      render json: @contacts
    end

    # GET /contacts/1
    def show
      #render json: { contact:  @contact.in_portuguese, message: "Success." }
      render json: @contact, include: [:kind, :address, :phone]
    end

    # POST /contacts
    def create
      @contact = Contact.new(contact_params)

      if @contact.save
        render json: @contact, status: :created, location: @contact
      else
        render json: @contact.errors, status: :unprocessable_entity
      end
    end

    # PATCH/PUT /contacts/1
    def update
      if @contact.update(contact_params)
        render json: @contact
      else
        render json: @contact.errors, status: :unprocessable_entity
      end
    end

    # DELETE /contacts/1
    def destroy
      @contact.destroy
    end

    private
      # Use callbacks to share common setup or constraints between actions.
      def set_contact
        @contact = Contact.find(params[:id])
      end

      # Only allow a list of trusted parameters through.
      def contact_params
         # params.require(:contact).permit(
         #   :name, :email, :birthdate, :kind_id, 
         #   phones_attributes: [:id, :number],
         #   address_attributes: [:id, :city, :street ]
         # )

        ActiveModelSerializers::Deserialization.jsonapi_parse(params)
      end
  end
end

Routes

Rails.application.routes.draw do
  resources :kinds

  # 127.0.0.1:3000/contacts?version=1
  #scope module: "v1", constraints: lambda{ |request| request.params[:version] == "1"} do
  api_version(:module => "V1", :path => {:value => "v1"}) do
    resources :contacts do 
      resource :kind, only: [:show]
      resource :kind, only: [:show], path: "relationships/kind"

      resource :phones, only: [:show]
      resource :phones, only: [:show], path: "relationships/phones"

      resource :address, only: [:show]
      resource :address, only: [:show], path: "relationships/address"
    end
  end

# 127.0.0.1:3000/contacts?version=2
#scope module: "v1", constraints: lambda{ |request| request.params[:version] == "2"} do
  api_version(:module => "V2", :path => {:value => "v2"}) do
    resources :contacts do 
      resource :kind, only: [:show]
      resource :kind, only: [:show], path: "relationships/kind"

      resource :phones, only: [:show]
      resource :phones, only: [:show], path: "relationships/phones"

      resource :address, only: [:show]
      resource :address, only: [:show], path: "relationships/address"
    end
end

   root "contacts#index"
end

GemFile

source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby "3.0.0"

# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
gem "rails", "~> 7.0.2", ">= 7.0.2.4"

# Use sqlite3 as the database for Active Record
gem "sqlite3", "~> 1.4"

# Use the Puma web server [https://github.com/puma/puma]
gem "puma", "~> 5.0"

# Build JSON APIs with ease [https://github.com/rails/jbuilder]
# gem "jbuilder"

# Use Redis adapter to run Action Cable in production
# gem "redis", "~> 4.0"

# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis]
# gem "kredis"

# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword]
# gem "bcrypt", "~> 3.1.7"

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ]

# Reduces boot times through caching; required in config/boot.rb
gem "bootsnap", require: false

# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images]
# gem "image_processing", "~> 1.2"

# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
 gem "rack-cors"

# ActiveModel::Serializer implementation and Rails hooks
 gem 'active_model_serializers', '~> 0.10.13'

 # Repository for collecting Locale data for Ruby on Rails I18n as well as other interesting, Rails related I18n stuff
 gem 'rails-i18n', '~> 7.0.0'

 gem 'faker', :git => 'https://github.com/faker-ruby/faker.git', :branch => 'master'

 # A plugin for versioning Rails based RESTful APIs
 gem 'versionist'

group :development, :test do
  # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
  gem "debug", platforms: %i[ mri mingw x64_mingw ]
end

group :development do
  # Speed up commands on slow machines / big apps [https://github.com/rails/spring]
  # gem "spring"
end
bploetz commented 2 years ago

@Vicente-jpro you're getting this error where/when exactly? When you start up your server? Can you paste the full stack trace?

bploetz commented 2 years ago

@Vicente-jpro I obviously don't have the full picture of your app (db, models, etc), but here's a skeleton mimicking what you have above that works fine for me:

https://github.com/bploetz/versionist-issue94

And after you start the server:

curl http://localhost:3000/v1/contacts.json
[{"version":"V1"}]

curl http://localhost:3000/v2/contacts.json
[{"version":"V2"}]