administrate
administrate copied to clipboard
How to scope dropdown options to current_user in forms
I'm loving this gem. I would like to scope dropdown options to the current_user and preferably without altering the Administrate controllers or views.
Surely there's an elegant way to achieve this?
Pundit scopes only seem to affect my index actions.
I'm looking to do something similar, can anyone lend a hand?
What dropdowns do you mean? Perhaps those of selector fields? If this is the case, perhaps you can create a new, custom field that inherits from Administrate::Field::Select
, and override selectable_options
to show the desired ones.
I think having scopes for belongs to and has many fields is important. It's a bit confusing that you can scope the resource being used for the index action of the controller, but not for the field types. Adding further confusion, these field types take a scope option, but, of course, the current_user
isn't available in the context of the dashboard classes. Currently, it looks like the way to deal with this is to generate custom fields and override a private method candidate_resources
. This process is a bit non-intuitive and I'm never psyched to work with or override private methods in a library I'm using. There's no guarantee that these won't change or go away in future releases.
I think this specific scope, a collection of things that belong to the current user, is fairly common. It's one of the things I reached for when I first started using this library. Would the core team be willing to create either belongs to and has many scoped fields or fields specifically designed to be scoped to the current user? It would be ideal/flexible for the user to just set a custom scope for the belongs to has many fields in whatever way they see fit, kind of like you allow people to set scoped_resource
in the controller. But even just something hard coded to work with the very common current_user
scope would be useful.
Right now I have a custom belongs to scoped to current user field that overrides candidate_resources
with:
def candidate_resources
scope = options[:scope] ? options[:scope].call : current_user.public_send(associated_class.to_s.downcase.pluralize).all
order = options.delete(:order)
order ? scope.reorder(order) : scope
end
Here's the full code: https://gist.github.com/elliotlarson/3d6c0c8260693a1715e7cfd159caf1d0
Not the most flexible approach, and again, not ideal to override a private method, but it works. However, I would feel better if this kind of hackery were maintained by the core team, or better yet, if the core team had a more elegant solution for introducing custom scopes into belongs to and has many fields.
I've been thinking of this scenario for a while. I would like to introduce something to provide more context to fields, but I haven't had much time to think what shape it would have. I don't want to rush it and end up not having added enough (or potentially, having added too much). Perhaps in the new year I'll have time for this... :-/