avo-hq / avo

Build Ruby on Rails apps 10x faster
https://avohq.io
Other
1.49k stars 232 forks source link

Has and belongs to many fields seem to be broken in 2.15.1? #1233

Closed iainbeeston closed 2 years ago

iainbeeston commented 2 years ago

Describe the bug

I've just upgrade from 2.14.2 to 2.15.1 and it is causing a rendering error in has and belongs to many fields across my app when using the grid view.

Here's the backtrace:

     Failure/Error: reflection_resource = field.resource

     ActionView::Template::Error:
       undefined method `resource' for nil:NilClass

             reflection_resource = field.resource
                                        ^^^^^^^^^

     [Screenshot Image]: /Users/iainbeeston/dev/plantheworld/forbes_marketplace/tmp/capybara/failures_r_spec_example_groups_website_articles_admin_is_possible_to_perform_crud_operations_on_articles_169.png

     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/components/avo/resource_component.rb:57:in `authorize_association_for'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/components/avo/index/resource_controls_component.rb:26:in `can_view?'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/components/avo/index/resource_controls_component.html.erb:5:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:130:in `block in render_template_for'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:93:in `synchronize'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:93:in `with_lock'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:128:in `render_template_for'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/base.rb:137:in `perform_render'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/base.rb:127:in `render_in'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/base.rb:210:in `render'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/components/avo/index/grid_item_component.html.erb:41:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:130:in `block in render_template_for'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:93:in `synchronize'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:93:in `with_lock'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:128:in `render_template_for'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/base.rb:137:in `perform_render'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/base.rb:127:in `render_in'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/base.rb:210:in `render'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/components/avo/index/resource_grid_component.html.erb:6:in `block (2 levels) in call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/components/avo/index/resource_grid_component.html.erb:5:in `block in call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/components/avo/index/resource_grid_component.html.erb:4:in `each'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/components/avo/index/resource_grid_component.html.erb:4:in `each_with_index'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/components/avo/index/resource_grid_component.html.erb:4:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:130:in `block in render_template_for'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:93:in `synchronize'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:93:in `with_lock'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:128:in `render_template_for'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/base.rb:137:in `perform_render'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/base.rb:127:in `render_in'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/base.rb:210:in `render'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/components/avo/views/resource_index_component.html.erb:68:in `block (3 levels) in call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/slot_v2.rb:58:in `to_s'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/components/avo/panel_component.html.erb:33:in `block in call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/components/avo/panel_component.html.erb:1:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:130:in `block in render_template_for'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:93:in `synchronize'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:93:in `with_lock'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:128:in `render_template_for'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/base.rb:137:in `perform_render'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/base.rb:127:in `render_in'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/base.rb:210:in `render'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/components/avo/views/resource_index_component.html.erb:5:in `block in call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/components/avo/views/resource_index_component.html.erb:1:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:130:in `block in render_template_for'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:93:in `synchronize'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:93:in `with_lock'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:128:in `render_template_for'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/base.rb:137:in `perform_render'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/base.rb:127:in `render_in'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/views/avo/base/index.html.erb:2:in `block in ___sers_iainbeeston__gem_ruby_______gems_avo________app_views_avo_base_index_html_erb__1768089902526893458_111000'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/base.rb:314:in `content'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/components/avo/turbo_frame_wrapper_component.html.erb:9:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:130:in `block in render_template_for'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:93:in `synchronize'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:93:in `with_lock'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/compiler.rb:128:in `render_template_for'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/base.rb:137:in `perform_render'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/view_component-2.60.0/lib/view_component/base.rb:127:in `render_in'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/views/avo/base/index.html.erb:1:in `___sers_iainbeeston__gem_ruby_______gems_avo________app_views_avo_base_index_html_erb__1768089902526893458_111000'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/meta-tags-2.17.0/lib/meta_tags/controller_helper.rb:22:in `render'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/controllers/avo/application_controller.rb:66:in `render'
     # <internal:kernel>:90:in `tap'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/i18n-1.12.0/lib/i18n.rb:322:in `with_locale'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/controllers/avo/application_controller.rb:310:in `set_avo_locale'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/actiontext-7.0.4/lib/action_text/rendering.rb:20:in `with_renderer'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/actiontext-7.0.4/lib/action_text/engine.rb:69:in `block (4 levels) in <class:Engine>'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/railties-7.0.4/lib/rails/engine.rb:530:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/railties-7.0.4/lib/rails/railtie.rb:226:in `public_send'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/railties-7.0.4/lib/rails/railtie.rb:226:in `method_missing'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/warden-1.2.9/lib/warden/manager.rb:36:in `block in call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/warden-1.2.9/lib/warden/manager.rb:34:in `catch'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/warden-1.2.9/lib/warden/manager.rb:34:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/rack-2.2.4/lib/rack/static.rb:161:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/rack-2.2.4/lib/rack/tempfile_reaper.rb:15:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/rack-2.2.4/lib/rack/etag.rb:27:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/rack-2.2.4/lib/rack/conditional_get.rb:27:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/rack-2.2.4/lib/rack/head.rb:12:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/rack-2.2.4/lib/rack/session/abstract/id.rb:266:in `context'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/rack-2.2.4/lib/rack/session/abstract/id.rb:260:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/bugsnag-6.24.2/lib/bugsnag/integrations/rack.rb:51:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/railties-7.0.4/lib/rails/rack/logger.rb:40:in `call_app'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/railties-7.0.4/lib/rails/rack/logger.rb:25:in `block in call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/railties-7.0.4/lib/rails/rack/logger.rb:25:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/request_store-1.5.1/lib/request_store/middleware.rb:19:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/rack-2.2.4/lib/rack/method_override.rb:24:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/rack-2.2.4/lib/rack/runtime.rb:22:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/rack-2.2.4/lib/rack/sendfile.rb:110:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/railties-7.0.4/lib/rails/engine.rb:530:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/rack-2.2.4/lib/rack/urlmap.rb:74:in `block in call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/rack-2.2.4/lib/rack/urlmap.rb:58:in `each'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/rack-2.2.4/lib/rack/urlmap.rb:58:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/rack-2.2.4/lib/rack/builder.rb:244:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/capybara-3.36.0/lib/capybara/server/animation_disabler.rb:26:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/capybara-3.36.0/lib/capybara/server/middleware.rb:60:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/puma-5.6.5/lib/puma/configuration.rb:252:in `call'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/puma-5.6.5/lib/puma/request.rb:77:in `block in handle_request'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/puma-5.6.5/lib/puma/thread_pool.rb:340:in `with_force_shutdown'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/puma-5.6.5/lib/puma/request.rb:76:in `handle_request'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/puma-5.6.5/lib/puma/server.rb:443:in `process_client'
     # /Users/iainbeeston/.gem/ruby/3.1.2/gems/puma-5.6.5/lib/puma/thread_pool.rb:147:in `block in spawn_thread'
     # ------------------
     # --- Caused by: ---
     # NoMethodError:
     #   undefined method `resource' for nil:NilClass
     #   
     #         reflection_resource = field.resource
     #                                    ^^^^^^^^^
     #   /Users/iainbeeston/.gem/ruby/3.1.2/gems/avo-2.15.1/app/components/avo/resource_component.rb:57:in `authorize_association_for'

Steps to Reproduce

Steps to reproduce the behavior:

  1. Add a field to your resource with this config: field :my_association, as: :has_and_belongs_to_many
  2. Open up avo in your browser and view this resource. It should render correctly when there are no associated models
  3. Attach or create an associated model in this field
  4. You should be on the show page for the resource. Switch the association from table view to grid view
  5. See error

Expected behavior & Actual behavior

You should now be on the show page for the resource. Previously the associated model would appear in a grid, but now there is an error.

Models and resource files

System configuration

Avo version: 2.15.1

Rails version: 7.0.4

Ruby version: 3.1.2

License type:

Screenshots

Additional context

Impact

Urgency

iainbeeston commented 2 years ago

I can reproduce this in the demo app too:

https://avodemo.herokuapp.com/avo/resources/users/avo-cado-0797905b-a7fd-4f1e-a409-3a860b931876

Just switch user teams to the grid view

adrianthedev commented 2 years ago

I see it. Thanks!

adrianthedev commented 2 years ago

Released in https://rubygems.org/gems/avo/versions/2.15.3