I added some code to the /lib/
directory in my rails app, which was not even recognised by rails probably due to loading, so I moved it to /app/lib/
then it was at least recognised, but not I get a NoMethodError when calling a method inside a module. Here is some of the code I placed in app/lib
# frozen_string_literal: true
module Github
module Auth
def connection
Faraday.new(
url: 'https://github.com'
)
end
def authorize
connection.get(
'/login/oauth/authorize',
params: {
client_id: '<My client id here>',
redirect_uri: '<My callback here>'
}
)
end
end
end
I then have an AuthorizeController
class, from which I want to call this code;
class AuthorizeController < ApplicationController
def index
response = Github::Auth.authorize
redirect_to response[:location] , allow_other_host: true
end
end
For which I get the following error:
Like I said, I moved the code from /lib/
to /app/lib/
which made Rails at least recognise the code, but this feels hacky to me and probably isn't the best way to do this. I also don't want to write an entire gem just for this functionality
I previously had this code inside the controller, but I want it to be in lib. What is the best practice to achieve this?
Thank you from a Rails noob! :)
CodePudding user response:
The error has nothing to do with the file location - rather if you want to define a "module method" you need to define it with self
:
module Github
module Auth
def self.connection
Faraday.new(
url: 'https://github.com'
)
end
def self.authorize
connection.get(
'/login/oauth/authorize',
params: {
client_id: '<My client id here>',
redirect_uri: '<My callback here>'
}
)
end
end
end
Instance methods of a module are only available within encapsulating objects - for example an instance of a class that includes the module.
You can also provide access to instance methods of a module from the singleton with the oddly named Module#module_function
method:
module Github
module Auth
def connection
Faraday.new(
url: 'https://github.com'
)
end
def authorize
connection.get(
'/login/oauth/authorize',
params: {
client_id: '<My client id here>',
redirect_uri: '<My callback here>'
}
)
end
module_function :connection, :authorize
end
end