devise_invitable icon indicating copy to clipboard operation
devise_invitable copied to clipboard

undefined method `has_invitations_left?' for true:TrueClass

Open wonderphil opened this issue 5 years ago • 1 comments

Hi

Firstly sorry if this isnt the right place to bring this up, but I am stuff trying to use invitable in a Rails API app. I followed on from https://www.codementor.io/@gowiem/deviseinvitable-rails-api-9wzmbisus but keep getting an error that I can seem to find any help with.

Run rails v6.0.2.2 devise_invitable (2.0.2) devise (4.7.1) Ruby 2.7.1

Routes:

Rails.application.routes.draw do
  mount Rswag::Ui::Engine => '/api-docs'
  mount Rswag::Api::Engine => '/api-docs'
  
  scope :api, defaults: { format: :json } do
    scope :v1, defaults: { format: :json } do
      devise_for :users, controllers: { 
                                        sessions: 'api/v1/sessions',
                                        invitations: 'api/v1/users/invitations' 
                                      },
                         path_names:  { sign_in: :login },
                         skip: [:passwords]
    end
  end
....

My controller to do overrides is /app/controller/api/v1/users/invitiations_controller.rb

# frozen_string_literal: true

module Api
  module V1
    class Users::InvitationsController < Devise::InvitationsController
      before_action :configure_permitted_parameters
      before_action :authenticate_user!

      def create
        User.invite!(invite_params, current_user)
        render json: { success: ['User created.'] }, status: :created
      end

      def edit
        sign_out send("current_#{resource_name}") if send("#{resource_name}_signed_in?")
        set_minimum_password_length
        resource.invitation_token = params[:invitation_token]
        redirect_to "http://localhost:3000/users/invitation/accept?invitation_token=#{params[:invitation_token]}"
      end

      def update
        super do |resource|
          if resource.errors.empty?
            render json: { status: "Invitation Accepted!" }, status: 200 and return
          else
            render json: resource.errors, status: 401 and return
          end
        end
      end

      private
      
      def configure_permitted_parameters
        devise_parameter_sanitizer.permit(:accept_invitation, keys: [:first_name, :last_name, :role_id])
      end
    end

  end
end

if I do a post request I get

oMethodError at /api/v1/users/invitation
=========================================

> undefined method `has_invitations_left?' for true:TrueClass

devise_invitable (2.0.2) app/controllers/devise/invitations_controller.rb, line 92
----------------------------------------------------------------------------------

 ruby
   87       def current_inviter
   88         authenticate_inviter!
   89       end
   90   
   91       def has_invitations_left?
>  92         unless current_inviter.nil? || current_inviter.has_invitations_left?
   93           self.resource = resource_class.new
   94           set_flash_message :alert, :no_invitations_remaining if is_flashing_format?
   95           respond_with_navigational(resource) { render :new }
   96         end
   97       end

I can provide full backtrace if needed.

The full request I am doing is:

curl -X "POST" "http://localhost:3000/api/v1/users/invitation" \
     -H 'Authorization: Bearer sometoken' \
     -H 'Content-Type: application/json' \
     -d $'{
  "users_invitation": {
    "email": "[email protected]",
    "first_name": "Philip",
    "last_name": "Davies"
  }
}'

wonderphil avatar Jun 09 '20 20:06 wonderphil

I don't think current_inviter must call authenticate_inviter!, it should probably be current_user.

scambra avatar Jun 10 '20 12:06 scambra