administrate icon indicating copy to clipboard operation
administrate copied to clipboard

Filtering Field::HasMany

Open vijuarez opened this issue 4 years ago • 10 comments

  • What would you like to be able to do? Can you provide some examples?

See, I've got a lot of users with different characteristics on my app. For example, they all have a role, which is an enum. Some models have references to users, but some of them have restrictions related to roles. For example, you can't select an user who's a guess to be the editor on a post. I've got all of that figured out via validations, but it would be nice to have it reflected on the interface. As if, when I start editing the editors attribute on a certain post, only users with the role author or admin appear as options.

  • How could we go about implementing that?

Passing some kind of filter (maybe a function) to the field on user_dashboard.rb would be nice.

  • Can you think of other approaches to the problem?

I could just filter it out during rendering (modifying the partial for Field::HasMany), but that's not nice to do if I want to do it on a lot of dashboards with many different conditions. A minimal example on how to do this would be extremely useful to me.

vijuarez avatar May 19 '21 22:05 vijuarez

I also had to go with modifying the partial.

szabcsee avatar May 25 '21 11:05 szabcsee

Yeah, I don't think there's a way to do this at the moment. Perhaps it would be a good idea to add a new option to the field that allows for this. It would probably have to modify HasMany#candidate_resources to use this new option. This is the concerned code:

https://github.com/thoughtbot/administrate/blob/b3bb0a3b7833deceff71cfe1687ac36cec12a6e8/lib/administrate/field/has_many.rb#L85-L92

Perhaps someone would like to volunteer a PR?

pablobm avatar Jun 10 '21 15:06 pablobm

I prepared a very rudimentary implementation here, but it's not that thought out. It would be probably better to pass scopes rather than plain where instructions, and I don't know how to filter with model methods. It's a start though.

https://github.com/vijuarez/administrate/blob/fd157d238f7f0049afac18edba1be22655c9cf3e/lib/administrate/field/has_many.rb#L85-L100

vijuarez avatar Jun 10 '21 22:06 vijuarez

Yup, that's the sort of thing we would need. I think it could be done better if it accepted a call-able instead, like a lambda. This is what we already do for Select and BelongsTo. For example:

https://github.com/thoughtbot/administrate/blob/9071a7eff60cbbcaf0ddc1b7bfb6bfe7d22b0028/lib/administrate/field/select.rb#L16-L23

pablobm avatar Jun 17 '21 15:06 pablobm

Hi! Stumbled upon this issue while needing filtering on HasMany as well.

Based on current implementation for BelongsTo, would it make sense to emulate it in HasMany?:

https://github.com/thoughtbot/administrate/compare/main...benoror:administrate:patch-1

benoror avatar Sep 21 '22 05:09 benoror

Found this extension that can achieve the same thing: https://github.com/XPBytes/administrate-field-scoped_has_many

benoror avatar Sep 22 '22 03:09 benoror

it would be great to just get this in here because that extension doesnt provide support for nice many-to-many fields etc, its just an awful html multiselect which is impossible to use for large options

9mm avatar May 12 '23 13:05 9mm

@9mm FWIW I ended up going back to default field and using this approach to scope results:

  • https://github.com/thoughtbot/administrate/blob/main/docs/guides/scoping_has_many_relations.md
  • https://github.com/SpointMX/spoint-backend/commit/6867623ffc46f64ea1a8cb745043cecff5ba96a0

benoror avatar May 12 '23 13:05 benoror

Awesome, thanks!

9mm avatar May 12 '23 13:05 9mm

I ended up disliking the Dropdown component used in XPBytes/administrate-field-scoped_has_many due to usability reasons.

I tried coming back to using the OG HasMany implementation from Administrate and the before-mentioned https://github.com/thoughtbot/administrate/blob/main/docs/guides/scoping_has_many_relations.md guide, but faced issues with :source param in a :through relationship, similarly as exposed here: https://github.com/thoughtbot/administrate/issues/681

I ended up MonkeyPatching to support a scope option, inspired by the [https://github.com/XPBytes/administrate-field-scoped_has_many/blob/4f13967cb405b94829ae75a22f100d29f2743b2c/lib/administrate/field/scoped_has_many.rb#L24C1-L29C1](very same XPBytes overriden implementation):

module Administrate
  module Field
    class HasMany < Associative
      private

      def candidate_resources
        puts options[:scope]
        scope = options[:scope] ? options[:scope].call(self) : associated_class.all
        scope = scope.includes(*options.fetch(:includes)) if options.key?(:includes)

        scope
      end
    end
  end
end

benoror avatar Jul 11 '23 20:07 benoror