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

WIP: Action-specific models #1506

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft

Conversation

pablobm
Copy link
Collaborator

@pablobm pablobm commented Dec 23, 2019

This is an experiment to see what would be the simplest way to implement #278 The idea here is to use database views to render index pages, allowing us to display and sort records in any way we please.

For the moment, I managed to make it work while only having to change Administrate's ApplicationController. In this change, new hooks are introduced to allow controller actions to use specific resource classes. Therefore the index action can use a model based off a view, while other actions keep using the default model based off a table.

As a result, this code can do three things:

  1. Order by a field in a belongs_to association. In the products index, the title of the product meta tag is shown, and it's possible to sort by it.
  2. Order by the result of an aggregate function. In the customers index, it's possible to sort customers by lifetime value.
  3. Eliminate the N+1 queries provoked by aggregate functions. In the customers index, the lifetime value is rendered from the result of the view. This is a bit more hacky as it involves a new definition for lifetime_value.

This is not quite there yet. For one, I managed to make index actions to work this way, but not show actions. There are new things that break and I need to look into.

Making the show action work would allow us to remove the lifetime_value methods from Customer and Customer::Index. The first is redundant with the view, and the second is only there to work around the first and avoid N+1 queries.

I should also add some tests specific to the features listed above.

To do:

  • Add documentation
  • How does this play with authorization? If an action uses a model other than the "base" model, the "base" authorization rules won't apply. At the very least, this should be documented.

@nickcharlton nickcharlton added dashboards how administrate presents fields and displays data feature new functionality that’s not yet implemented labels Jan 2, 2020
@pablobm
Copy link
Collaborator Author

pablobm commented Jan 16, 2020

@nickcharlton, would you be able to have a look at this and see if it's worthwhile, before I spend more time on it? I want to make sure I'm not deviating from Administrate's spirit, or some similarly fundamental problem.

@nickcharlton
Copy link
Member

@pablobm, I think this sounds like a good approach.

Do you think you'd be able to add some draft documentation next so we can see how you might use this? (just a comment is fine, I think…)

@cabe56
Copy link
Contributor

cabe56 commented Sep 5, 2020

@nickcharlton I can help out with this, where do you suggest we put docs for this feature?

Was looking at /docs but wasn't sure if you'd like to add a new .md file or mention it elsewhere.

Edit: maybe another option would be putting a section in customizing_dashboards.md

@pablobm
Copy link
Collaborator Author

pablobm commented Sep 12, 2020

Thank you for your interest @cabe56. I had parked this PR while I worked on something else.

I had envisioned two ways of documenting this feature:

  • Document public methods of Administrate::ApplicationController with YARD, to make it easy for developers to find out what interfaces are available.

  • A new section in the Administrate documentation in a "how to" style. Here we could explain how to make Administrate work in the various use cases and configurations that we get asked about. Devise do this at https://github.com/heartcombo/devise/wiki/How-Tos.

Now, the problem is that Administrate doesn't yet have either! We haven't started documenting methods, and we don't have a "how to" section in the docs. I was thinking of doing that first so that this PR can get a place where to include its documentation.

From your comment, I understand that you have an interest in this feature? If you could provide help, like a review, testing in your own projects, or a how-to document, that would be great.

@pablobm pablobm force-pushed the multimodel branch 2 times, most recently from 47b66f1 to cb7cae5 Compare September 12, 2020 15:33
@cabe56
Copy link
Contributor

cabe56 commented Sep 28, 2020

@pablobm great ideas, I think that would help making Administrate more accessible. As you mention, these are not used in the project and I think incorporating them could be a barrier to getting this awesome feature shipped.

Focused (short-term) on how to get your change through this review, I re-read @nickcharlton's suggestion and I think he meant just adding a quick snippet/comment/tl;dr on how to use this feature.

I'll post back here once I try this PR out on my project. Thanks for taking the time to build this!

Customer::Index
else
super
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a-ha. Here is the missing piece. Looks good.

A second approach could be placing something in CustomersDashboard, maybe like:

action_classes = {
  index: Customer::Index
}

...which would leave less for the developer to worry about, because all of the logic is in the dashboard class.

Maybe; I've been gone a while so I'm unsure if the second approach is sound.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. I'm still unsure though, of where Administrate should be adding dashboard options and where it shouldn't. In general, the feature introduced in this PR feels to me like something that should be supported, but that in reality won't be used that often. For this reason, it doesn't necessarily deserve more explicit configuration options, as these become a maintenance burden later for little benefit.

It may still be a good idea, but the benefit of starting the feature at a controller level is that we can delay adding new dashboard-level options later.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense. Adding action-specific models seems like a niche usage, so overriding the controller is a good approach.

@original_product_policy = Product.policy_class
Product.policy_class = TestProductPolicy
@original_log_entry_policy = LogEntry.policy_class
LogEntry.policy_class = TestLogEntryPolicy
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, glad you can re-use some code here.

Copy link
Collaborator Author

@pablobm pablobm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your reviews @c4lliope. I left it as a draft while it got some initial reviews and I worked on other things. Currently I'm making an effort to pick up the drafts I've left behind and actually finalising them. At the moment I'm focused on #1941, and I plan to move on to this one when done.

Customer::Index
else
super
end
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. I'm still unsure though, of where Administrate should be adding dashboard options and where it shouldn't. In general, the feature introduced in this PR feels to me like something that should be supported, but that in reality won't be used that often. For this reason, it doesn't necessarily deserve more explicit configuration options, as these become a maintenance burden later for little benefit.

It may still be a good idea, but the benefit of starting the feature at a controller level is that we can delay adding new dashboard-level options later.

spec/example_app/app/models/product.rb Show resolved Hide resolved
@pablobm pablobm changed the title Action-specific models WIP: Action-specific models Apr 22, 2021
@pablobm pablobm closed this Jun 24, 2021
@pablobm pablobm deleted the multimodel branch June 24, 2021 10:40
@pablobm pablobm restored the multimodel branch December 16, 2021 09:36
@pablobm
Copy link
Collaborator Author

pablobm commented Dec 16, 2021

I don't remember why I closed this...? Re-opening for now, although I'm still a bit far from being able to work on it.

@pablobm pablobm reopened this Dec 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dashboards how administrate presents fields and displays data feature new functionality that’s not yet implemented
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants