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

0.1.4 makes eager loading fail #9

Open
PikachuEXE opened this issue Jul 4, 2016 · 15 comments
Open

0.1.4 makes eager loading fail #9

PikachuEXE opened this issue Jul 4, 2016 · 15 comments

Comments

@PikachuEXE
Copy link

PikachuEXE commented Jul 4, 2016

I tried to update from 0.1.2 > 0.1.4
reform 2.2.1

Code:

require "reform"
require "reform/rails"

class SomeForm < Reform::Form
     include Reform::Form::ActiveModel::Validations

     # property...
end

Got the same error with or without include

Error Log

/users/pikachuexe/projects/spacious/spacious-rails/app/controllers/api/lister_app/v1/listings/create_controller.rb:107: warning: toplevel constant ActiveModel referenced by Reform::Form::ActiveModel
/users/pikachuexe/projects/spacious/spacious-rails/app/controllers/api/lister_app/v1/listings/update_controller.rb:139: warning: toplevel constant ActiveModel referenced by Reform::Form::ActiveModel
/users/pikachuexe/projects/spacious/spacious-rails/app/controllers/api/lister_app/v1/my/lister_profile/update_controller.rb:148: warning: toplevel constant ActiveModel referenced by Reform::Form::ActiveModel
/users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/reform-2.2.1/lib/reform/validation.rb:6:in `validation_groups': undefined local variable or method `validation_group_class' for Api::ListerApp::V1::PropertyImages::CreateController::Form:Class (NameError)
Did you mean?  validation_groups
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/reform-2.2.1/lib/reform/validation.rb:13:in `validation'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/reform-2.2.1/lib/reform/validation.rb:19:in `validates'
    from /users/pikachuexe/projects/spacious/spacious-rails/app/controllers/api/lister_app/v1/property_images/create_controller.rb:138:in `<class:Form>'
    from /users/pikachuexe/projects/spacious/spacious-rails/app/controllers/api/lister_app/v1/property_images/create_controller.rb:134:in `<class:CreateController>'
    from /users/pikachuexe/projects/spacious/spacious-rails/app/controllers/api/lister_app/v1/property_images/create_controller.rb:9:in `<module:PropertyImages>'
    from /users/pikachuexe/projects/spacious/spacious-rails/app/controllers/api/lister_app/v1/property_images/create_controller.rb:8:in `<module:V1>'
    from /users/pikachuexe/projects/spacious/spacious-rails/app/controllers/api/lister_app/v1/property_images/create_controller.rb:7:in `<module:ListerApp>'
    from /users/pikachuexe/projects/spacious/spacious-rails/app/controllers/api/lister_app/v1/property_images/create_controller.rb:6:in `<module:Api>'
    from /users/pikachuexe/projects/spacious/spacious-rails/app/controllers/api/lister_app/v1/property_images/create_controller.rb:5:in `<top (required)>'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/activesupport-4.1.15/lib/active_support/dependencies.rb:247:in `require'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/activesupport-4.1.15/lib/active_support/dependencies.rb:247:in `block in require'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/activesupport-4.1.15/lib/active_support/dependencies.rb:232:in `load_dependency'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/activesupport-4.1.15/lib/active_support/dependencies.rb:247:in `require'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/activesupport-4.1.15/lib/active_support/dependencies.rb:348:in `require_or_load'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/activesupport-4.1.15/lib/active_support/dependencies.rb:307:in `depend_on'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/activesupport-4.1.15/lib/active_support/dependencies.rb:225:in `require_dependency'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/railties-4.1.15/lib/rails/engine.rb:468:in `block (2 levels) in eager_load!'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/railties-4.1.15/lib/rails/engine.rb:467:in `each'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/railties-4.1.15/lib/rails/engine.rb:467:in `block in eager_load!'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/railties-4.1.15/lib/rails/engine.rb:465:in `each'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/railties-4.1.15/lib/rails/engine.rb:465:in `eager_load!'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/railties-4.1.15/lib/rails/engine.rb:346:in `eager_load!'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/railties-4.1.15/lib/rails/application/finisher.rb:58:in `each'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/railties-4.1.15/lib/rails/application/finisher.rb:58:in `block in <module:Finisher>'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/railties-4.1.15/lib/rails/initializable.rb:30:in `instance_exec'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/railties-4.1.15/lib/rails/initializable.rb:30:in `run'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/railties-4.1.15/lib/rails/initializable.rb:55:in `block in run_initializers'
    from /Users/PikachuEXE/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:228:in `block in tsort_each'
    from /Users/PikachuEXE/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
    from /Users/PikachuEXE/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:431:in `each_strongly_connected_component_from'
    from /Users/PikachuEXE/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:349:in `block in each_strongly_connected_component'
    from /Users/PikachuEXE/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:347:in `each'
    from /Users/PikachuEXE/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:347:in `call'
    from /Users/PikachuEXE/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:347:in `each_strongly_connected_component'
    from /Users/PikachuEXE/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:226:in `tsort_each'
    from /Users/PikachuEXE/.rvm/rubies/ruby-2.3.1/lib/ruby/2.3.0/tsort.rb:205:in `tsort_each'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/railties-4.1.15/lib/rails/initializable.rb:54:in `run_initializers'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/railties-4.1.15/lib/rails/application.rb:300:in `initialize!'
    from /users/pikachuexe/projects/spacious/spacious-rails/config/environment.rb:5:in `<top (required)>'
    from /users/pikachuexe/projects/spacious/spacious-rails/spec/spec_helper.rb:13:in `require'
    from /users/pikachuexe/projects/spacious/spacious-rails/spec/spec_helper.rb:13:in `block in <top (required)>'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/spork-1.0.0rc4/lib/spork.rb:24:in `prefork'
    from /users/pikachuexe/projects/spacious/spacious-rails/spec/spec_helper.rb:9:in `<top (required)>'
    from /users/pikachuexe/projects/spacious/spacious-rails/spec/rails_helper.rb:1:in `require_relative'
    from /users/pikachuexe/projects/spacious/spacious-rails/spec/rails_helper.rb:1:in `<top (required)>'
    from /users/pikachuexe/projects/spacious/spacious-rails/spec/controllers/users/omniauth_callbacks_controller_spec.rb:1:in `require'
    from /users/pikachuexe/projects/spacious/spacious-rails/spec/controllers/users/omniauth_callbacks_controller_spec.rb:1:in `<top (required)>'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/rspec-core-3.5.0/lib/rspec/core/configuration.rb:1435:in `load'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/rspec-core-3.5.0/lib/rspec/core/configuration.rb:1435:in `block in load_spec_files'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/rspec-core-3.5.0/lib/rspec/core/configuration.rb:1433:in `each'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/rspec-core-3.5.0/lib/rspec/core/configuration.rb:1433:in `load_spec_files'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/rspec-core-3.5.0/lib/rspec/core/runner.rb:100:in `setup'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/rspec-core-3.5.0/lib/rspec/core/runner.rb:86:in `run'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/rspec-core-3.5.0/lib/rspec/core/runner.rb:71:in `run'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/rspec-core-3.5.0/lib/rspec/core/runner.rb:45:in `invoke'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/gems/rspec-core-3.5.0/exe/rspec:4:in `<top (required)>'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/bin/rspec:22:in `load'
    from /users/pikachuexe/.rvm/gems/ruby-2.3.1/bin/rspec:22:in `<top (required)>'
    from -e:1:in `load'
    from -e:1:in `<main>'
@apotonick
Copy link
Member

Your application config, please. I have no idea how "eager loading" works.

@PikachuEXE
Copy link
Author

Sure please see below

Main line for eager load:

config.eager_load = true

config/application.rb

require File.expand_path('../boot', __FILE__)

# Pick the frameworks you want:
require "active_record/railtie"
require "action_controller/railtie"
require "action_mailer/railtie"
require "sprockets/railtie"
# require "rails/test_unit/railtie"

if defined?(Bundler)
  # Require the gems listed in Gemfile, including any gems
  # you've limited to :test, :development, or :production.
  Bundler.require(:default, Rails.env)
end

module Spacious
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded.

    # Make our web page gzipped
    config.middleware.insert_before(ActionDispatch::Static, Rack::Deflater)

    # Concerns (Already in Rails 4)
    config.autoload_paths += %W(
      #{config.root}/app/controllers/concerns
      #{config.root}/app/models/concerns
      #{config.root}/app/concepts
    )

    # Force SSL to be used
    ssl_enforcer_options = {
      except_agents: [/Baiduspider/i, /MSIE [6|7|8]/i],
      ignore: [%r|/assets|i, '/robots.txt', %r|/api|, %r|/health_check|],
      # We want to enforce HTTP to HTTPS for some domains
      # We DON't want to enforce HTTPS to HTTP for other domains
      strict: false,
      # DON't enable this until you know what is this
      hsts: nil,
    }
    if ENV["HTTP_PORT"]
      ssl_enforcer_options.merge!(http_port: ENV["HTTP_PORT"])
    end
    if ENV["HTTPS_PORT"]
      ssl_enforcer_options.merge!(https_port: ENV["HTTPS_PORT"])
    end
    config.middleware.use "Rack::SslEnforcerCustomized", ssl_enforcer_options

    # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
    # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
    config.time_zone = 'Hong Kong'

    # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
    # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
    config.i18n.default_locale = :en
    # For now we only have en
    config.i18n.available_locales = [:en, :'zh-TW', :'zh-CN', :'zh-HK']
    # Enforce to check if assigned locale is included in available_locales
    config.i18n.enforce_available_locales = true

    # Configure the default encoding used in templates for Ruby 1.9.
    config.encoding = "utf-8"

    # Enable escaping HTML in JSON.
    config.active_support.escape_html_entities_in_json = true

    # Rescue error with our app
    config.exceptions_app = self.routes

    # ActionMailer template root path
    ActionMailer::Base.prepend_view_path(Rails.root.join("app/views/mailers"))

    # Use SQL instead of Active Record's schema dumper when creating the database.
    # This is necessary if your schema can't be completely dumped by the schema dumper,
    # like if you have constraints or database-specific column types
    # config.active_record.schema_format = :sql

    # Version of your assets, change this if you want to expire all your assets
    config.assets.version = '1.0'

    # was turned off to resolve issue with heroku precompile
    #   http://devcenter.heroku.com/articles/rails3x-asset-pipeline-cedar
    # now turned on as we use `heroku labs:enable user-env-compile`
    config.assets.initialize_on_precompile = true

    # assets;
    config.assets.precompile += [
      # rails admin needs these
      "rails_admin/rails_admin.js",
      "rails_admin/rails_admin.css",
      "rails_admin/jquery.colorpicker.js",
      "rails_admin/jquery.colorpicker.css",

      # Script run in head
      "html5shiv.js",
      "head.js",
    ]
    # Fix for sprocket-rails
    # http://blog.xdite.net/posts/2014/01/29/rails4-asset-mess
    # https://github.com/rails/rails/pull/7968
    config.assets.precompile += %w(*.png *.jpg *.jpeg *.gif)

    # Since `sprockets-rails` 2.1.0
    config.assets.raise_runtime_errors = true

    # we don't want too much boilerplate
    config.generators.template_engine :haml
    config.generators.helper = false
    config.generators.assets = false
    config.generators.test_framework :rspec, view_specs: false
    config.generators.fixture_replacement :factory_girl, dir: 'spec/factories'
    config.generators.orm :active_record

    config.log_level = (
          [
              (ENV![:LOG_LEVEL] || ::Rails.application.config.log_level).to_s.upcase,
              "INFO",
          ] & %w[DEBUG INFO WARN ERROR FATAL UNKNOWN]
        ).compact.first


    ### Redis
    config.redis_url = ENV![:REDIS_URL]

    # Caching
    config.use_memcache = false
    config.use_redis_for_caching = false
  end
end

config/environments/development.rb

Rails.application.class.configure do
  # Settings specified here will take precedence over those in config/application.rb

  # In the development environment your application's code is reloaded on
  # every request. This slows down response time but is perfect for development
  # since you don't have to restart the web server when you make code changes.
  config.cache_classes = false

  # Do not eager load code on boot.
  config.eager_load = true

  # Show full error reports and disable caching
  config.consider_all_requests_local       = true
  config.action_controller.perform_caching = true

  # Print deprecation notices to the Rails logger
  config.active_support.deprecation = :log

  # Use a different cache store based on memcached is running or not
  config.memcache_servers = nil
  config.dalli_client_options = {
    namespace: Rails.application.class.parent_name,
    expires_in: 1.day,
    compress: true,
  }
  begin
    # check if memcached is running; if it is, use that instead of the default memory cache
    Timeout.timeout(0.5) { TCPSocket.open("localhost", 11211) { } }

    config.memcache_servers = %w(localhost:11211)
    config.use_memcache = true
    config.cache_store = :dalli_store, config.memcache_servers, config.dalli_client_options

    $stderr.puts "Using memcached on localhost:11211"
  rescue StandardError
    $stderr.puts "memcached not running, caching to memory"
  end

  # Do not compress assets
  config.assets.compress = false

  # Expands the lines which load the assets
  config.assets.debug = true

  # Raise error for missing asset
  config.assets.raise_runtime_errors = true

  ### Email related
  ## Send email to mailcatcher
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
      address:        'localhost',
      port:           1025,
  }
  # change to true to allow email to be sent during development
  config.action_mailer.perform_deliveries = true
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.default charset: "utf-8"
  config.action_mailer.default_url_options = {
      host: AppConfig.default_domain,
      port: 3000,
  }


  ### Development tools
  BetterErrors.use_pry!
  AwesomePrint.defaults = { plain: true }

  # Raises error for missing translations
  config.action_view.raise_on_missing_translations = true
end

@PikachuEXE PikachuEXE changed the title 0.1.4 makes eagar loading fail 0.1.4 makes eager loading fail Jul 4, 2016
@PikachuEXE
Copy link
Author

This issue still exists in 0.1.5
Anything missing that I should provide?

@coding-red-panda
Copy link

Is there any update to this?
Cause Reform is 100% not working under Rails 5 anymore with this problem.

@apotonick
Copy link
Member

@coding-bunny Can you provide a minimal Rails 5 app provoking this? I can have a quick look now.

@coding-red-panda
Copy link

coding-red-panda commented Jun 7, 2017

Euh, exact code needs a bit of time, but in real short:

  • Rails 5 application out of the box
  • Create a folder under app called re_form_objects
  • Create a basic form object
  • create a basic extension under app/re_form_objects
  • Follow the Rails 5 approach to auto_load and eager_load

Some example of one of our FormObjects:

# frozen_string_literal: true
# file location: app/re_form_objects/password_reset.rb
module ReFormObjects
  class PasswordReset < ::ReFormObjects::Base
    include ::ReFormObjects::PasswordValidations

    model :user

    validates :password, presence: true
    validate :existing_user
    validate :reset_token_still_valid

    property :password
    property :password_confirmation
    property :reset_password_sent_at, writeable: false
    property :reset_password_token, writeable: false
    property :unlock_token, writeable: false

    private

    def existing_user
      errors.add(:base, I18n.t('devise.failure.invalid_token')) unless model.persisted?
    end

    def reset_token_still_valid
      return if reset_password_sent_at.blank? || reset_password_sent_at > 6.hours.ago
      errors.add(:base, I18n.t('devise.failure.invalid_token'))
    end

    def user
      model
    end
  end
end

The included module

# location: app/re_form_objects/password_validations.rb
module ReFormObjects
  module PasswordValidations
    extend ActiveSupport::Concern

    included do
      validate :validate_password_length, if: :password_needs_length_validation?
      validates :password,
                confirmation: true,
                format: {
                  with: %r{\A(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*(_|[^\w])).+\z},
                  allow_blank: true,
                  message: -> (_, _) { I18n.t('errors.messages.password.invalid') }
                }
    end

    def password_errors
      return '' if errors[:password].empty?
      errors[:password].to_sentence
    end
  end
end

application.rb
This is the snippet on how we're currently debugging the eager loading and auto loading under rails 5, as we recently upgraded:

module MyApplication
  class Application < Rails::Application
    
    # TODO: Remove me once code is confirmed working
    config.eager_loading = true

    # Custom directories with classes and modules you want to be autoloadable.
    # Rails automatically loads app/*, so we do not need to add those ourselves normally.
    # However because we violate naming conventions, we explicitly add it to be safe.
    # TODO: Follow naming conventions and remove these entries
    config.autoload_paths += %W(#{config.root}/app/**/*.rb)

    # Eager Loading
    # This behaviour changed in Rails 5.
    # Just because something is added to the auto_load_path, doesn't guarantee it works in production.
    # This is because the code outside the app folder is not eager loaded by rails unless explicitly required.
    # To prevent this, we're going to add the folders we need to the eager_loading_path
    # TODO: Follow naming conventions and remove these entries
    config.eager_load_paths += %W(#{config.root}/app/**/*.rb)
  end
end

I think i might be able to get everything going again by adding

require 'reform'
require 'reform/rails'

At the top of our application.rb, but not sure if this is supposed to be the way to go, as I expect Bundler to handle this for us.

@apotonick
Copy link
Member

Writing that up probably took longer than hacking down the code 😂

Thanks, will check it out.

@apotonick
Copy link
Member

BTW, this problem doesn't exist when you use trailblazer-loader and the TRB file structure for your forms, it's highly recommended checking that out.

@coding-red-panda
Copy link

at this point I'm open for trying anything to get it to work

@apotonick
Copy link
Member

Give me a sample Rails app, the less I have to do the quicker you get a fix.

@coding-red-panda
Copy link

I'll try to set something up and post it here as soon as I can

@coding-red-panda
Copy link

I've created a new Rails 5 application copying over the minimal parts and it works actually.
So out of the box it actually works just fine with the configuration set up the same.

My guess there's a specific setting that breaks everything in the framework, which I'm going to try and hunt down now

@apotonick
Copy link
Member

@coding-bunny Can you jump on https://gitter.im/trailblazer/chat for a few mins, I can help diagnosing.

@coding-red-panda
Copy link

joined

@coding-red-panda
Copy link

just for reference here:

  1. I added require rails/all to our application.rb again
  2. I regenerated the spec_helper and rails_helper from rspec
  3. moved all code in lib to app/lib
  4. extended the autoload and eager_load paths like so:
config.autoload_paths += %W(#{config.root}/app)
config.eager_load_paths += %W(#{config.root}/app)
config.eager_loading = true

And this makes the loading errors and undefined consts disappear for us.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants