I have a Rails 7 app with Doorkeeper 5.8.1. In my app I have mixins for DoorKeeper Application, AccessToken, and AccessGrant using extend ActiveSupport::Concern
. As an example
# app/models/concerns/my_mixin.rb
module MyMixin
extend ActiveSupport::Concern
included do
has_one :other_obj, foreign_key: :id, class_name: "OtherObj"
validates :api_key, uniqueness: true, allow_nil: true
validates_length_of :api_key, minimum: 32, allow_blank: true
end
def my_method(input) do
# do something with input.
other_obj.process(input)
end
end
Doorkeeper::Application.include MyMixin
When I upgraded to Rails 8, unit tests for DoorKeeper::Application.my_method(test_input)
fail with
NoMethodError: undefined method 'my_method' for an instance of Doorkeeper::Application
Did something change between Rails 7 and 8 that I'm missing?
A much better approach than monkeypatching is to just configure Doorkeeper to use your own classes:
# config/initializers/doorkeeper.rb
Doorkeeper.configure do
# ...
# You can use your own model classes if you need to extend (or even override) default
# Doorkeeper models such as `Application`, `AccessToken` and `AccessGrant.
#
# By default Doorkeeper ActiveRecord ORM uses its own classes:
#
# access_token_class "Doorkeeper::AccessToken"
# access_grant_class "Doorkeeper::AccessGrant"
application_class "MyApplication"
# ...
end
class MyApplication < Doorkeeper::Application
has_one :other_obj, foreign_key: :id, class_name: "OtherObj"
validates :api_key, uniqueness: true, allow_nil: true
validates_length_of :api_key, minimum: 32, allow_blank: true
def my_method(input) do
# do something with input.
other_obj.process(input)
end
end
Using modules to monkeypatch classes that are not yours should always be a last resort.
Did something change between Rails 7 and 8 that I'm missing?
Maybe. But it could have been that the monkeypatch worked when the code was eager loaded or that another test had previously caused the module to be required.
If you're gonna monkeypatch do it explicitly (in an initializer) instead of having the autoloader do it implicitly when the file is loaded. It's also a good practice to separate the file that defines the monkeypatch from the "injection" as it lets you test it without side effects.