Doorkeeper: [Discussion] Revisit approach to let users extend models

Created on 19 Nov 2019  Â·  4Comments  Â·  Source: doorkeeper-gem/doorkeeper

In many scenarios an app needs to extend a Doorkeeper::Application and Doorkeeper::AccessToken model.

I have an app running in production where we needed to extend those for different features, and I know I'm not the first.

It currently feels very hacky that the gem's users have to research proper ways to extending - some will just try monkey-patching and find issues. Others will try module prepend, and then will face issues with Rails reloader.

I think this gem is great, but I think the path that it took to define its models in an extensible way is just not mature as many apps need.

I think the maintainers should consider accepting a proposal for a more extensible approach, found in gems like Devise - you're responsible for providing the model and them we could just include the Doorkeeper's module/concern in there. That would let the users do whatever the want with the model without any hacks.

enhancement questiodiscussion

Most helpful comment

I created a PoC branch here - https://github.com/doorkeeper-gem/doorkeeper/tree/configurable-models

It has extracted AR mixins and configuration options to define own classes that would be used by Doorkeeper as a models. So everybody can just do:

# config/initializers/doorkeeper.rb
Doorkeeper.configure do
  access_token_class "MyToken"
  access_grant_class "MyGrant"
  application_class "Client"
end

# app/models/my_token.rb
class MyToken < ActiveRecord::Base
  include ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessToken

  before_create :send_message

  def send_message
    SlackClient.new.deliver("Heey, I've hacked Doorkeeper models!")
  end
end

# ... and so on ...

By default Doorkeeper configured to use current gem AR models so it must not break existing projects. But only if you didn't patched the internals :grimacing: :grimacing: :grimacing:

I didn't implement some Rails Wayâ„¢ DSL like acts_as_access_token - you can do it on your own, I like pure Ruby.

Anyone could take this branch and try it on his/her project with Doorkeeper and propose a PR if everything works or with some additional improvements.

All 4 comments

Hi @rafaelsales . It's a great thread! Totally agree.

But here we can face some issue, at least incompatibility with previous versions. So it could be done only in some major version. Anyway feel free to propose a PR! I like the idea with mixins, I'm already implemented it this way in my https://github.com/grape-oauth2/grape_oauth2 gem a few years ago

I created a PoC branch here - https://github.com/doorkeeper-gem/doorkeeper/tree/configurable-models

It has extracted AR mixins and configuration options to define own classes that would be used by Doorkeeper as a models. So everybody can just do:

# config/initializers/doorkeeper.rb
Doorkeeper.configure do
  access_token_class "MyToken"
  access_grant_class "MyGrant"
  application_class "Client"
end

# app/models/my_token.rb
class MyToken < ActiveRecord::Base
  include ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessToken

  before_create :send_message

  def send_message
    SlackClient.new.deliver("Heey, I've hacked Doorkeeper models!")
  end
end

# ... and so on ...

By default Doorkeeper configured to use current gem AR models so it must not break existing projects. But only if you didn't patched the internals :grimacing: :grimacing: :grimacing:

I didn't implement some Rails Wayâ„¢ DSL like acts_as_access_token - you can do it on your own, I like pure Ruby.

Anyone could take this branch and try it on his/her project with Doorkeeper and propose a PR if everything works or with some additional improvements.

OK, so I've merged a solution proposed above. Would be available with 5.3.0 release. So now everybody have an ability to customize Doorkeeper models without hacks with include/prepend . Enjoy and let me know if there are some issues

For example:

Doorkeeper.configure do
  access_token_class "MyAccessToken"
  # ...
end

# app/models/my_access_token.rb
class MyAccessToken < ApplicationRecord
  include ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessToken

  self.table_name = "hey_i_wanna_my_name"

  def destroy_me!
     destroy
  end
end

Added this to my new doorkeeper powered rails app today. So far it works like a charm!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

iangreenleaf picture iangreenleaf  Â·  4Comments

krtschmr picture krtschmr  Â·  6Comments

anidhya picture anidhya  Â·  5Comments

eebasadre picture eebasadre  Â·  4Comments

f3ndot picture f3ndot  Â·  3Comments