hashrocket / decent_exposure

A helper for creating declarative interfaces in controllers
MIT License
1.81k stars 107 forks source link

Can't use :from with any other option #164

Open lukeredpath opened 8 years ago

lukeredpath commented 8 years ago

Trying to use :from with :with raises an error that using any other option with :from doesn't make any sense.

Doesn't it?

I want to authorise my models using Pundit. I want to do this by calling authorize - I don't care how the model was loaded.

An easy way of doing this would be to use decorate:

expose :foo, decorate: ->(foo) { foo.tap { authorize(foo) } }

The pattern is common enough I'd probably want to wrap it up isn an exposure config:

exposure_config :authorization, decorate: ->(obj) { obj.tap { authorize(obj) } }

Now I can just do:

expose :foo, with: :authorization

Great! Now I have a singleton resource I'd like to load as an association from the logged in user:

expose :organisation, from: :current_user

But I want it authorised too:

expose :organisation, from: :current_user, with: :authorization

But this doesn't work as I can't use with and from together.

I can't do this either:

expose :organisation, fetch: -> { current_user.organisation }, with: :authorization

I can only do this:

expose :organisation, fetch: -> { current_user.organisation.tap { |o| authorize(o) } }

But now I'm duplicating my call to authorize, something I'd prefer to keep encapsulated.

Is there a reason to make these options mutually exclusive, just because sometimes they don't make sense to use together? Does the library need to be this restrictive?

hazah commented 7 years ago

It would seem to me that this can be resolved by calling normalize_with_option before the asserts in the initialize method. Given that :with options are to simply a pointer to some defaults, it makes sense that these defaults be included in the asserts rather than the option pointing to them.

hazah commented 6 years ago

175

lukeredpath commented 6 years ago

πŸŽ‰πŸŽ‰πŸŽ‰