railsadminteam / rails_admin

RailsAdmin is a Rails engine that provides an easy-to-use interface for managing your data
MIT License
7.88k stars 2.25k forks source link

Problem migration with not (yet) existing fields: NoMethodError: undefined method `defined' for nil:NilClass unless f.defined #3546

Closed jklimke closed 1 year ago

jklimke commented 2 years ago

Situation:

A developer that has to execute the added migrations to its development database. As there were many fields (e.g., :short_name) added to some models, there are referenced in Rails admin concerns, e.g.,

module Admin
  module AssetPropertyAdmin
    extend ActiveSupport::Concern

    included do
     rails_admin do
         # :short_name is added in a migration that has not been executed yet.
         fields :short_name, :name
     end
   end
  end
end

We are then not able to execute the migrations or start the server as the initialization of rails admin does not proceed.

The following error is thrown

rake aborted!
NoMethodError: undefined method `defined' for nil:NilClass
          unless f.defined
                  ^^^^^^^^
/home/user/.rvm/gems/ruby-3.1.2/gems/rails_admin-3.1.0.beta/lib/rails_admin/config/has_fields.rb:93:in `block in fields'
/home/user/.rvm/gems/ruby-3.1.2/gems/rails_admin-3.1.0.beta/lib/rails_admin/config/has_fields.rb:92:in `collect'
/home/user/.rvm/gems/ruby-3.1.2/gems/rails_admin-3.1.0.beta/lib/rails_admin/config/has_fields.rb:92:in `fields'
/home/user/projects/rails_app/app/models/concerns/admin/asset_property_admin.rb:25:in `block (3 levels) in <module:AssetPropertyAdmin>'
/home/user/.rvm/gems/ruby-3.1.2/gems/rails_admin-3.1.0.beta/lib/rails_admin/config/sections.rb:32:in `instance_eval'
/home/user/.rvm/gems/ruby-3.1.2/gems/rails_admin-3.1.0.beta/lib/rails_admin/config/sections.rb:32:in `block (2 levels) in included'
/home/user/projects/rails_app/app/models/concerns/admin/asset_property_admin.rb:24:in `block (2 levels) in <module:AssetPropertyAdmin>'
/home/user/.rvm/gems/ruby-3.1.2/gems/rails_admin-3.1.0.beta/lib/rails_admin/config.rb:261:in `instance_eval'
/home/user/.rvm/gems/ruby-3.1.2/gems/rails_admin-3.1.0.beta/lib/rails_admin/config.rb:261:in `model'
/home/user/.rvm/gems/ruby-3.1.2/gems/rails_admin-3.1.0.beta/config/initializers/active_record_extensions.rb:8:in `block in rails_admin'
/home/user/.rvm/gems/ruby-3.1.2/gems/rails_admin-3.1.0.beta/lib/rails_admin/config.rb:93:in `block in initialize!'
/home/user/.rvm/gems/ruby-3.1.2/gems/rails_admin-3.1.0.beta/lib/rails_admin/config.rb:93:in `each'
/home/user/.rvm/gems/ruby-3.1.2/gems/rails_admin-3.1.0.beta/lib/rails_admin/config.rb:93:in `initialize!'
/home/user/.rvm/gems/ruby-3.1.2/gems/rails_admin-3.1.0.beta/lib/rails_admin/engine.rb:39:in `block in <class:Engine>'
/home/user/.rvm/gems/ruby-3.1.2/gems/railties-6.1.6/lib/rails/initializable.rb:32:in `instance_exec'
/home/user/.rvm/gems/ruby-3.1.2/gems/railties-6.1.6/lib/rails/initializable.rb:32:in `run'
/home/user/.rvm/gems/ruby-3.1.2/gems/railties-6.1.6/lib/rails/initializable.rb:61:in `block in run_initializers'
/home/user/.rvm/gems/ruby-3.1.2/gems/railties-6.1.6/lib/rails/initializable.rb:60:in `run_initializers'
/home/user/.rvm/gems/ruby-3.1.2/gems/railties-6.1.6/lib/rails/application.rb:391:in `initialize!'
/home/user/projects/rails_app/config/environment.rb:5:in `<main>'
/home/user/.rvm/gems/ruby-3.1.2/gems/bootsnap-1.12.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/home/user/.rvm/gems/ruby-3.1.2/gems/bootsnap-1.12.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:30:in `require'
/home/user/.rvm/gems/ruby-3.1.2/gems/zeitwerk-2.6.0/lib/zeitwerk/kernel.rb:35:in `require'
/home/user/.rvm/gems/ruby-3.1.2/gems/activesupport-6.1.6/lib/active_support/dependencies.rb:332:in `block in require'
/home/user/.rvm/gems/ruby-3.1.2/gems/activesupport-6.1.6/lib/active_support/dependencies.rb:299:in `load_dependency'
/home/user/.rvm/gems/ruby-3.1.2/gems/activesupport-6.1.6/lib/active_support/dependencies.rb:332:in `require'
/home/user/.rvm/gems/ruby-3.1.2/gems/railties-6.1.6/lib/rails/application.rb:367:in `require_environment!'
/home/user/.rvm/gems/ruby-3.1.2/gems/railties-6.1.6/lib/rails/application.rb:533:in `block in run_tasks_blocks'
/home/user/.rvm/gems/ruby-3.1.2/gems/airbrake-10.0.6/lib/airbrake/rake.rb:19:in `execute'
/home/user/.rvm/gems/ruby-3.1.2/bin/ruby_executable_hooks:22:in `eval'
/home/user/.rvm/gems/ruby-3.1.2/bin/ruby_executable_hooks:22:in `<main>'
Tasks: TOP => db:migrate => db:load_config => environment
(See full trace by running task with --trace)

How is it meant to work ?

It seems that this line can in fact return nil members in the array:

https://github.com/railsadminteam/rails_admin/blob/ce1bb5a1c166b62412e4032b2d1f798297a7c289/lib/rails_admin/config/has_fields.rb#L90

that causes the follwing block to fail:

https://github.com/railsadminteam/rails_admin/blob/ce1bb5a1c166b62412e4032b2d1f798297a7c289/lib/rails_admin/config/has_fields.rb#L92

it can be fixed by compacting the defined array.

defined.compact.collect do |f|
  unless f.defined
    f.defined = true
    f.order = _fields.count(&:defined)
  end
  f.instance_eval(&block) if block
  f
end

Any oppinions on that ? Could you either apply the change or provide a hint how could this be avoided that rails admin crashes on not (yet) existing fields ?

mshibuya commented 2 years ago

Could you try with the master branch? I guess #3541 will solve this.

gem 'rails_admin', github: 'railsadminteam/rails_admin'
jklimke commented 2 years ago

Could you try with the master branch? I guess #3541 will solve this.

gem 'rails_admin', github: 'railsadminteam/rails_admin'

This seems to solve the issue as the models are loaded deferred again. Nevertheless i did not manage to build a docker deployment with the current master as the webpacker build fails in my CI and on docker hub. Is it possible that there wer issues introduced that cause these processes to fail or to consume a lot more resources.

The error produced does not make any sense to me. The scss files are the ones generate by rails admin.

ERROR in ./app/javascript/stylesheets/rails_admin.scss (./node_modules/css-loader/dist/cjs.js??ref--8-1!./node_modules/postcss-loader/src??ref--8-2!./node_modules/resolve-url-loader!./node_modules/sass-loader/dist/cjs.js??ref--8-4!./app/javascript/stylesheets/rails_admin.scss)
Module build failed (from ./node_modules/postcss-loader/src/index.js):
ParserError: Syntax Error at line: 1, column 30
    at /builds/tasa_hpi/tasa_web/app/javascript/stylesheets/rails_admin.scss:9:1165
    at Parser.error (/builds/tasa_hpi/tasa_web/node_modules/postcss-values-parser/lib/parser.js:127:11)
    at Parser.operator (/builds/tasa_hpi/tasa_web/node_modules/postcss-values-parser/lib/parser.js:162:20)
    at Parser.parseTokens (/builds/tasa_hpi/tasa_web/node_modules/postcss-values-parser/lib/parser.js:245:14)
    at Parser.loop (/builds/tasa_hpi/tasa_web/node_modules/postcss-values-parser/lib/parser.js:132:12)
    at Parser.parse (/builds/tasa_hpi/tasa_web/node_modules/postcss-values-parser/lib/parser.js:51:17)
    at parse (/builds/tasa_hpi/tasa_web/node_modules/postcss-custom-properties/index.cjs.js:47:30)
    at /builds/tasa_hpi/tasa_web/node_modules/postcss-custom-properties/index.cjs.js:333:24
    at /builds/tasa_hpi/tasa_web/node_modules/postcss/lib/container.js:194:18
    at /builds/tasa_hpi/tasa_web/node_modules/postcss/lib/container.js:139:18
    at Rule.each (/builds/tasa_hpi/tasa_web/node_modules/postcss/lib/container.js:105:16)
    at Rule.walk (/builds/tasa_hpi/tasa_web/node_modules/postcss/lib/container.js:135:17)
    at /builds/tasa_hpi/tasa_web/node_modules/postcss/lib/container.js:152:24
    at Root.each (/builds/tasa_hpi/tasa_web/node_modules/postcss/lib/container.js:105:16)
    at Root.walk (/builds/tasa_hpi/tasa_web/node_modules/postcss/lib/container.js:135:17)
    at Root.walkDecls (/builds/tasa_hpi/tasa_web/node_modules/postcss/lib/container.js:[192](https://gitlab.hpi3d.de/tasa_hpi/tasa_web/-/jobs/203799#L192):19)
    at transformProperties (/builds/tasa_hpi/tasa_web/node_modules/postcss-custom-properties/index.cjs.js:330:8)
    at Object.syncTransform [as plugin] (/builds/tasa_hpi/tasa_web/node_modules/postcss-custom-properties/index.cjs.js:522:5)
    at /builds/tasa_hpi/tasa_web/node_modules/postcss-preset-env/index.js:459:97
 @ ./app/javascript/stylesheets/rails_admin.scss 2:26-278
 @ ./app/javascript/packs/rails_admin.js
mshibuya commented 2 years ago

What do you have in app/javascript/stylesheets/rails_admin.scss ?

jklimke commented 2 years ago

basically it includes

@import "rails_admin/src/rails_admin/styles/base.scss";

Meanwhile i was able to hunt it down to a issue in postcss-values-parser and sass packages. It unfortunately took a lot of hours.

It seems related with this webpacker issue in webpacker: https://github.com/rails/webpacker/issues/3188 There seem to be SCSS issues in fontawesome and bootstrap that are causing this: https://github.com/twbs/bootstrap/pull/35033 https://github.com/FortAwesome/Font-Awesome/issues/18899

You should maybe think about upgrading fontawesome to 6.2 when it is available.

I locked my sass implementation to 1.39.0 an it seems to compiles again in docker and asset precompilation.

Anyway, thanks for your support.