Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Administrate::Punditize methods as module methods #2403

Merged
merged 1 commit into from
Oct 13, 2023

Conversation

jordan-brough
Copy link
Contributor

@jordan-brough jordan-brough commented Jul 21, 2023

Instead of adding them via included do.


Note: It's easiest to view this diff if you hide whitespace changes:
image


If these methods are added via included do it makes it hard to override the method in an app's controller.

Example:

module Admin
  class ApplicationController < Administrate::ApplicationController
    include Administrate::Punditize

    def scoped_resource
      super.where(archived: false)
    end
  end
end

That example will skip pundit completely, because the def scoped_resource from Administrate::Punditize was added via included do, which means it will behave as if we had defined the method inline twice in Admin ::ApplicationController, which will result in the first definition from Administrate::Punditize being ignored. And the super in the code snippet above will refer to the non-punditized definition provided in the base class Administrate::ApplicationController:

def scoped_resource
resource_class.default_scoped
end

This seems unexpected to me, and makes it hard to add functionality that layers on top of what Administrate::Punditize does.

However, if we define def scoped_resource as a module method in Administrate::Punditize then super in Admin::ApplicationController will refer to the method defined in Administrate::Punditize.

Are there gotchas that I'm missing? Is there a reason that some of the methods
in Administrate::Punditize were defined via included do and others were
added as module methods?

Instead of adding them via `included do`.

If they are added via "included do" it makes it hard to override the method
in an app's controller.

Example:

```ruby
module Admin
  class ApplicationController < Administrate::ApplicationController
    include Administrate::Punditize

    def scoped_resource
      super.where(archived: false)
    end
  end
end
```

That example will skip pundit completely, because the `def scoped_resource` from
`Administrate::Punditize` was added via `included do`, which means it will
behave as if we had defined the method twice in `Admin ::ApplicationController`,
which will result in the first definition from `Administrate::Punditize` being
ignored. And "super" will refer to the no-op definition provided in the base
class `Administrate::ApplicationController`.

This seems unexpected to me, and makes it hard to add functionality that layers
on to pof what `Administrate::Punditize` does.

However, if we defined `def scoped_resource` as a module method in
`Administrate::Punditize` then `super` in `Admin::ApplicationController` will
refer to the method defined in `Administrate::Punditize`.
@pablobm
Copy link
Collaborator

pablobm commented Aug 4, 2023

Thank you for this PR @jordan-brough. What you say makes sense to me. I don't know why this was implemented as a concern in the first place. In fact, would we need extend ActiveSupport::Concern any more?

Let me ping @nickcharlton to triple check that we are not missing anything here.

@pablobm
Copy link
Collaborator

pablobm commented Oct 13, 2023

This has waited long enough. Merging. If it breaks something... we'll be let know!

@pablobm pablobm merged commit 84badf2 into thoughtbot:main Oct 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants