Upgrading from 1.4 to 1.5 beta failed due to plugin


(Dia) #1

I upgraded to the latest version of Discourse via the admin dashboard, but the the upgrade failed towards the end with the exception shown at the end of the post. However, what’s interesting is that the site still loads fine and the admin dashboard indicates that I’m at version (v1.5.0.beta2 +13) and that I should update. When I click on the click on the upgrade link, it takes me to the /admin/upgrade page, but that page indicates that I’m at the latest version. I haven’t noticed any specific issues with the site. My concern is that the upgrade process left the forum in an improper state, especially with regards to DB migrations. What do you suggest I do?

I, [2015-10-06T07:05:40.142294 #37]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate'
rake aborted!
NameError: wrong constant name #<Class:0x007fba63da3890>
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/seed-fu-2.3.5/lib/seed-fu/runner.rb:46:in `eval'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/core_ext/module/qualified_const.rb:30:in `block in qualified_const_defined?'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/core_ext/module/qualified_const.rb:29:in `each'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/core_ext/module/qualified_const.rb:29:in `inject'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/core_ext/module/qualified_const.rb:29:in `qualified_const_defined?'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/dependencies.rb:376:in `qualified_const_defined?'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/dependencies.rb:478:in `load_missing_constant'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/dependencies.rb:184:in `const_missing'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/inflector/methods.rb:276:in `const_get'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/inflector/methods.rb:276:in `block in constantize'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/inflector/methods.rb:259:in `each'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/inflector/methods.rb:259:in `inject'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/inflector/methods.rb:259:in `constantize'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/inflector/methods.rb:304:in `safe_constantize'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/dependencies.rb:572:in `safe_get'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/dependencies.rb:603:in `safe_constantize'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/inheritance.rb:154:in `block in compute_type'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/inheritance.rb:153:in `each'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/inheritance.rb:153:in `compute_type'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/reflection.rb:271:in `compute_class'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/reflection.rb:267:in `klass'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/associations/association.rb:118:in `klass'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/associations/association.rb:176:in `find_target?'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/associations/association.rb:138:in `load_target'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/associations/association.rb:53:in `reload'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/associations/singular_association.rb:9:in `reader'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/associations/builder/association.rb:115:in `user_avatar'
/var/www/discourse/app/models/user.rb:749:in `refresh_avatar'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:432:in `block in make_lambda'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:228:in `call'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:228:in `block in halting_and_conditional'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:506:in `call'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:506:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:506:in `each'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:506:in `call'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:92:in `__run_callbacks__'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/callbacks.rb:778:in `_run_save_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/callbacks.rb:302:in `create_or_update'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/persistence.rb:120:in `save'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/validations.rb:37:in `save'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/attribute_methods/dirty.rb:21:in `save'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/transactions.rb:286:in `block (2 levels) in save'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/transactions.rb:351:in `block in with_transaction_returning_status'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/database_statements.rb:211:in `transaction'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/transactions.rb:220:in `transaction'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/transactions.rb:348:in `with_transaction_returning_status'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/transactions.rb:286:in `block in save'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/transactions.rb:301:in `rollback_active_record_state!'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/transactions.rb:285:in `save'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/seed-fu-2.3.5/lib/seed-fu/seeder.rb:74:in `seed_record'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/seed-fu-2.3.5/lib/seed-fu/seeder.rb:36:in `block (2 levels) in seed'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/seed-fu-2.3.5/lib/seed-fu/seeder.rb:36:in `map'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/seed-fu-2.3.5/lib/seed-fu/seeder.rb:36:in `block in seed'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/database_statements.rb:211:in `transaction'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/transactions.rb:220:in `transaction'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/seed-fu-2.3.5/lib/seed-fu/seeder.rb:35:in `seed'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/seed-fu-2.3.5/lib/seed-fu/active_record_extension.rb:32:in `seed'
(eval):9:in `block (2 levels) in run_file'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/seed-fu-2.3.5/lib/seed-fu/runner.rb:46:in `eval'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/seed-fu-2.3.5/lib/seed-fu/runner.rb:46:in `block (2 levels) in run_file'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/seed-fu-2.3.5/lib/seed-fu/runner.rb:58:in `block in open'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/seed-fu-2.3.5/lib/seed-fu/runner.rb:57:in `open'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/seed-fu-2.3.5/lib/seed-fu/runner.rb:57:in `open'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/seed-fu-2.3.5/lib/seed-fu/runner.rb:36:in `block in run_file'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `block in transaction'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/transaction.rb:184:in `within_new_transaction'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `transaction'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activerecord-4.2.4/lib/active_record/transactions.rb:220:in `transaction'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/seed-fu-2.3.5/lib/seed-fu/runner.rb:35:in `run_file'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/seed-fu-2.3.5/lib/seed-fu/runner.rb:26:in `block in run'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/seed-fu-2.3.5/lib/seed-fu/runner.rb:25:in `each'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/seed-fu-2.3.5/lib/seed-fu/runner.rb:25:in `run'
/var/www/discourse/vendor/bundle/ruby/2.0.0/gems/seed-fu-2.3.5/lib/seed-fu.rb:29:in `seed'
/var/www/discourse/lib/tasks/db.rake:8:in `block in <top (required)>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

(Dia) #2

I’ve tried rebuilding the docker image, and I got the same exception. But now, it has brought down the site, unsurprisingly. Any pointers as to why this is happening?


(Kane York) #3

Any non-standard plugins installed?


(Dia) #4

Yeah, I was thinking the same thing. I have only one custom plugin that handles some custom authentication logic. I’m still looking into it and whether it may be causing it.


(Dia) #5

Yep, seems related to the plugin. I disabled it and now the image rebuilds successfully. I’m debugging the plugin to find out what is causing it.

Did anything change in 1.5 with respect to how plugins work?


(Dia) #6

After investigation, it seems like the root cause is using the prepend ruby method to extend the User class.

I’ve stripped out everything in the plugin to the bare minimum to reproduce it. Here’s the plugin:

after_initialize do
  module UserExtensions
    def foobar
      # dummy method
    end
  end
    
  User.class_eval do
    prepend UserExtensions
  end
end

This alone reproduces the problem. I found a simple way to reproduce it by running the following in rails console:

pry(main)> User.reflect_on_association(:posts).klass
NameError: wrong constant name #<Class:0x007ff2cf3e3450>
from /var/www/discourse/vendor/bundle/ruby/2.0.0/gems/activesupport-4.2.4/lib/active_support/core_ext/module/qualified_const.rb:30:in `const_defined?'

I’m using the prepend approach to extend some functionality in the User class. This used to work in version 1.4, but errors out in 1.5. Not sure if this is a Rails issue or Discourse. Anyone know why this is happening?

update: I tested using prepend with other classes (e.g. Post), and the same exception happens. So it’s not specific to the User class.


(Neil Lalonde) #7

You can use the plugin extensibility methods add_to_class and add_class_method to do that safely.


(Dia) #8

Good to know, didn’t know about these methods. One question I have is how can add_to_class be used to extend an existing method in the base class and be able to call the super method within the new implementation? That’s actually the main reason I’m using the prepend approach.