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

Using mounted method within params #2321

Closed
Nix41 opened this issue May 4, 2023 · 5 comments
Closed

Using mounted method within params #2321

Nix41 opened this issue May 4, 2023 · 5 comments
Labels

Comments

@Nix41
Copy link

Nix41 commented May 4, 2023

When constructing a namespace, where options are passed through the configuration hash
In order to declare the params using the entity set in the configuration, as per the documentation:

params do
  requires :all, using: mounted { configuration[:entity] }.documentation
end
post do
  resource = configuration[:model].create!(
  present resource, with: mounted { configuration[:entity] }
end

Results in:

NoMethodError:
  undefined method `mounted' for #<Grape::Validations::ParamsScope:0x00007f1a325c2df0 @element=nil, @element_renamed=nil, @parent=nil, @api=#<Class:0x00007f1a325cc508>, @optional=false, @type=Hash, @group=nil, @dependent_on=nil, @declared_params=[], @index=nil>

The mounted method, does seem to be accessible via the @api variable within Grape::Validations::ParamsScope
Maybe I am missing something?

In any case, thanks in advance for taking a look

Here the full backtrace or the Error:
# ./app/api/admin_dashboard/resources/templates/crud.rb:21:in `block (2 levels) in <class:Crud>'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/validations/params_scope.rb:70:in `instance_eval'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/validations/params_scope.rb:70:in `initialize'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/dsl/validations.rb:39:in `new'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/dsl/validations.rb:39:in `params'
# ./app/api/admin_dashboard/resources/templates/crud.rb:20:in `block in <class:Crud>'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api/instance.rb:118:in `instance_eval'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api/instance.rb:118:in `block in evaluate_as_instance_with_configuration'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/util/lazy_block.rb:11:in `evaluate_from'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api/instance.rb:125:in `evaluate_as_instance_with_configuration'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api/instance.rb:107:in `block in nest'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api/instance.rb:107:in `each'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api/instance.rb:107:in `nest'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/dsl/routing.rb:175:in `block in namespace'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/dsl/settings.rb:160:in `within_namespace'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/dsl/routing.rb:172:in `namespace'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api.rb:160:in `replay_step_on'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api.rb:151:in `block in add_setup'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api.rb:150:in `each'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api.rb:150:in `add_setup'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api.rb:55:in `block (2 levels) in override_all_methods!'
# ./app/api/admin_dashboard/resources/templates/crud.rb:10:in `<class:Crud>'
# ./app/api/admin_dashboard/resources/templates/crud.rb:6:in `<module:Templates>'
# ./app/api/admin_dashboard/resources/templates/crud.rb:5:in `<module:Resources>'
# ./app/api/admin_dashboard/resources/templates/crud.rb:4:in `<module:AdminDashboard>'
# ./app/api/admin_dashboard/resources/templates/crud.rb:3:in `<top (required)>'
# /usr/share/rvm/gems/ruby-3.1.3/gems/zeitwerk-2.6.8/lib/zeitwerk/kernel.rb:30:in `require'
# /usr/share/rvm/gems/ruby-3.1.3/gems/zeitwerk-2.6.8/lib/zeitwerk/kernel.rb:30:in `require'
# ./app/api/admin_dashboard/resources/admins.rb:7:in `block in <class:Admins>'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api/instance.rb:118:in `instance_eval'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api/instance.rb:118:in `block in evaluate_as_instance_with_configuration'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/util/lazy_block.rb:11:in `evaluate_from'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api/instance.rb:125:in `evaluate_as_instance_with_configuration'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api/instance.rb:107:in `block in nest'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api/instance.rb:107:in `each'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api/instance.rb:107:in `nest'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/dsl/routing.rb:175:in `block in namespace'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/dsl/settings.rb:160:in `within_namespace'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/dsl/routing.rb:172:in `namespace'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api.rb:160:in `replay_step_on'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api.rb:151:in `block in add_setup'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api.rb:150:in `each'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api.rb:150:in `add_setup'
# /usr/share/rvm/gems/ruby-3.1.3/gems/grape-1.7.0/lib/grape/api.rb:55:in `block (2 levels) in override_all_methods!'
# ./app/api/admin_dashboard/resources/admins.rb:6:in `<class:Admins>'
# ./app/api/admin_dashboard/resources/admins.rb:5:in `<module:Resources>'
# ./app/api/admin_dashboard/resources/admins.rb:4:in `<module:AdminDashboard>'
# ./app/api/admin_dashboard/resources/admins.rb:3:in `<top (required)>'
# /usr/share/rvm/gems/ruby-3.1.3/gems/zeitwerk-2.6.8/lib/zeitwerk/kernel.rb:30:in `require'
# /usr/share/rvm/gems/ruby-3.1.3/gems/zeitwerk-2.6.8/lib/zeitwerk/kernel.rb:30:in `require'
# ./app/api/admin_dashboard/base.rb:19:in `<class:Base>'
# ./app/api/admin_dashboard/base.rb:4:in `<module:AdminDashboard>'
# ./app/api/admin_dashboard/base.rb:3:in `<top (required)>'
# /usr/share/rvm/gems/ruby-3.1.3/gems/zeitwerk-2.6.8/lib/zeitwerk/kernel.rb:30:in `require'
# /usr/share/rvm/gems/ruby-3.1.3/gems/zeitwerk-2.6.8/lib/zeitwerk/kernel.rb:30:in `require'
# ./app/api/api.rb:59:in `<class:Api>'
# ./app/api/api.rb:5:in `<module:Api>'
# ./app/api/api.rb:4:in `<top (required)>'
# /usr/share/rvm/gems/ruby-3.1.3/gems/zeitwerk-2.6.8/lib/zeitwerk/kernel.rb:30:in `require'
# /usr/share/rvm/gems/ruby-3.1.3/gems/zeitwerk-2.6.8/lib/zeitwerk/kernel.rb:30:in `require'
# ./config/routes.rb:812:in `block in <top (required)>'
# /usr/share/rvm/gems/ruby-3.1.3/gems/actionpack-7.0.4.3/lib/action_dispatch/routing/route_set.rb:428:in `instance_exec'
# /usr/share/rvm/gems/ruby-3.1.3/gems/actionpack-7.0.4.3/lib/action_dispatch/routing/route_set.rb:428:in `eval_block'
# /usr/share/rvm/gems/ruby-3.1.3/gems/actionpack-7.0.4.3/lib/action_dispatch/routing/route_set.rb:410:in `draw'
# ./config/routes.rb:7:in `<top (required)>'
# /usr/share/rvm/gems/ruby-3.1.3/gems/railties-7.0.4.3/lib/rails/application/routes_reloader.rb:50:in `load'
# /usr/share/rvm/gems/ruby-3.1.3/gems/railties-7.0.4.3/lib/rails/application/routes_reloader.rb:50:in `block in load_paths'
# /usr/share/rvm/gems/ruby-3.1.3/gems/railties-7.0.4.3/lib/rails/application/routes_reloader.rb:50:in `each'
# /usr/share/rvm/gems/ruby-3.1.3/gems/railties-7.0.4.3/lib/rails/application/routes_reloader.rb:50:in `load_paths'
# /usr/share/rvm/gems/ruby-3.1.3/gems/railties-7.0.4.3/lib/rails/application/routes_reloader.rb:24:in `reload!'
# /usr/share/rvm/gems/ruby-3.1.3/gems/railties-7.0.4.3/lib/rails/application.rb:149:in `reload_routes!'
# /usr/share/rvm/gems/ruby-3.1.3/gems/devise-4.9.2/lib/devise/rails.rb:17:in `block in <class:Engine>'
# /usr/share/rvm/gems/ruby-3.1.3/gems/activesupport-7.0.4.3/lib/active_support/lazy_load_hooks.rb:92:in `block in execute_hook'
# /usr/share/rvm/gems/ruby-3.1.3/gems/activesupport-7.0.4.3/lib/active_support/lazy_load_hooks.rb:85:in `with_execution_control'
# /usr/share/rvm/gems/ruby-3.1.3/gems/activesupport-7.0.4.3/lib/active_support/lazy_load_hooks.rb:90:in `execute_hook'
# /usr/share/rvm/gems/ruby-3.1.3/gems/activesupport-7.0.4.3/lib/active_support/lazy_load_hooks.rb:76:in `block in run_load_hooks'
# /usr/share/rvm/gems/ruby-3.1.3/gems/activesupport-7.0.4.3/lib/active_support/lazy_load_hooks.rb:75:in `each'
# /usr/share/rvm/gems/ruby-3.1.3/gems/activesupport-7.0.4.3/lib/active_support/lazy_load_hooks.rb:75:in `run_load_hooks'
# /usr/share/rvm/gems/ruby-3.1.3/gems/railties-7.0.4.3/lib/rails/application/finisher.rb:73:in `block in <module:Finisher>'
# /usr/share/rvm/gems/ruby-3.1.3/gems/railties-7.0.4.3/lib/rails/initializable.rb:32:in `instance_exec'
# /usr/share/rvm/gems/ruby-3.1.3/gems/railties-7.0.4.3/lib/rails/initializable.rb:32:in `run'
# /usr/share/rvm/gems/ruby-3.1.3/gems/railties-7.0.4.3/lib/rails/initializable.rb:61:in `block in run_initializers'
# /usr/share/rvm/gems/ruby-3.1.3/gems/railties-7.0.4.3/lib/rails/initializable.rb:60:in `run_initializers'
# /usr/share/rvm/gems/ruby-3.1.3/gems/railties-7.0.4.3/lib/rails/application.rb:372:in `initialize!'
# ./config/environment.rb:5:in `<top (required)>'
# ./spec/rails_helper.rb:6:in `require'
# ./spec/rails_helper.rb:6:in `<top (required)>'
Here the rest of the relevant code
# frozen_string_literal: true

module AdminDashboard
  module Resources
    class Admins < Base
      resource :admins do
        mount Resources::Templates::Crud, with: { index: Admin.all, entity: Entities::Admin }
      end
    end
  end
end
# frozen_string_literal: true

module AdminDashboard
  module Resources
    module Templates
      class Crud < Base
        include Grape::Kaminari

        namespace do
          params do
            use :pagination, per_page: 10, max_per_page: 30
          end
          get do
            list = configuration[:index]

            present paginate(list), with: mounted { configuration[:entity] }
          end

          params do
            requires :all, using: mounted { configuration[:entity] }.documentation
          end
          post do
            resource = configuration[:model].create!(permitted_params)

            present resource, with: mounted { configuration[:entity] }
          end
        end
      end
    end
  end
end
@dblock
Copy link
Member

dblock commented May 4, 2023

I don't think you're missing anything. Try adding it to ParamScope?

@Nix41
Copy link
Author

Nix41 commented May 4, 2023

Hi @dblock , thanks for answering, as far as I can see, the code is as the documentation specifies, specifically: https://github.com/ruby-grape/grape#mount-configuration , I should be able to do this without modifying the gem, right?
This is why I thought this might be a bug, and not a new feature

@dblock
Copy link
Member

dblock commented May 5, 2023

Ah I see. Yes, that would be a bug. Care to add a (failing) test?

@myxoh
Copy link
Member

myxoh commented Jun 20, 2023

Hi - this is my bad as clearly I got overly eager on the docs.

We can fix it in one of two ways:

First just update the docs. The behaviour described on those docs is achievable without the mounted { } block (that block is really only needed for top-level configuration that is evaluated at the class level - while the params block is only really evaluated after the endpoint is mounted (and therefore doesn't need to be lazy loaded)

Alternatively: Define the mounted block in ParamsScope - I don't really think there's much value in doing it this way - but we certainly can define a dummy mounted block for consistency.

Added this PR: #2339

@dblock
Copy link
Member

dblock commented Jun 22, 2023

Closed via #2339

@dblock dblock closed this as completed Jun 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants