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

undefined method 'define_dynamic_method' during rake db:migrate #455

Closed
ndbroadbent opened this issue Jun 30, 2017 · 4 comments
Closed

undefined method 'define_dynamic_method' during rake db:migrate #455

ndbroadbent opened this issue Jun 30, 2017 · 4 comments

Comments

@ndbroadbent
Copy link

ndbroadbent commented Jun 30, 2017

I wanted to create a migration to move my admin boolean flags into Roles. My migration looks like this:

class MigrateRolesToRolify < ActiveRecord::Migration[5.0]
  def up
    User.all.each do |user|
      if user.admin?
        user.add_role :admin
      end
    end
  end
end

When I run rake db:migrate, I get the following error:

== 20170630154905 MigrateRolesToRolify: migrating =============================
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

undefined method `define_dynamic_method' for #<Class:0x007fbdc4f94eb0>
Did you mean?  define_method
/Users/ndbroadbent/.rvm/gems/ruby-2.3.3/gems/activerecord-5.0.2/lib/active_record/dynamic_matchers.rb:21:in `method_missing'
/Users/ndbroadbent/.rvm/gems/ruby-2.3.3/gems/rolify-5.1.0/lib/rolify/role.rb:18:in `add_role'
/Users/ndbroadbent/code/my_app/db/migrate/20170630154905_migrate_roles_to_rolify.rb:6:in `block in up'
/Users/ndbroadbent/.rvm/gems/ruby-2.3.3/gems/activerecord-5.0.2/lib/active_record/relation/delegation.rb:38:in `each'
/Users/ndbroadbent/.rvm/gems/ruby-2.3.3/gems/activerecord-5.0.2/lib/active_record/relation/delegation.rb:38:in `each'
/Users/ndbroadbent/code/my_app/db/migrate/20170630154905_migrate_roles_to_rolify.rb:3:in `up'
/Users/ndbroadbent/.rvm/gems/ruby-2.3.3/gems/activerecord-5.0.2/lib/active_record/migration.rb:792:in `exec_migration'
/Users/ndbroadbent/.rvm/gems/ruby-2.3.3/gems/activerecord-5.0.2/lib/active_record/migration.rb:773:in `block (2 levels) in migrate'
/Users/ndbroadbent/.rvm/gems/ruby-2.3.3/gems/activerecord-5.0.2/lib/active_record/migration.rb:772:in `block in migrate'

Any idea why this might be happening?

(FYI, it works fine if I run user.add_role :admin in the Rails console.)

NOTE: In my logs you can see that I was testing on Rails 5.0.2. I just updated to Rails 5.1.2 and am seeing the same error.

@ndbroadbent
Copy link
Author

ndbroadbent commented Jun 30, 2017

Update - Actually it does crash in the Rails console if I run:

User.all.each do |user|
  if user.admin?
    user.add_role :admin
  end
end

@ndbroadbent
Copy link
Author

Ah, I think there's a bug in Rolify. Rolify.dynamic_shortcuts is not true when the app is first loading, but it is set to true later on. So the Dynamic module is not being extended.

I added a debugger statement to lib/rolify.rb to show how that is happening:

[12, 21] in /Users/ndbroadbent/.rvm/gems/ruby-2.3.3/gems/rolify-5.1.0/lib/rolify.rb
   12:   @@resource_types = []
   13:
   14:   def rolify(options = {})
   15:     include Role
   16:     debugger
=> 17:     extend Dynamic if Rolify.dynamic_shortcuts
   18:
   19:     options.reverse_merge!({:role_cname => 'Role'})
   20:     self.role_cname = options[:role_cname]
   21:     self.role_table_name = self.role_cname.tableize.gsub(/\//, "_")
(byebug) Rolify.dynamic_shortcuts
false
(byebug) c

Running via Spring preloader in process 75374
Loading development environment (Rails 5.1.2)
irb: warn: can't alias context from irb_context.
2.3.3 :001 >   Rolify.dynamic_shortcuts
 => true
2.3.3 :002 >

@ndbroadbent
Copy link
Author

ndbroadbent commented Jun 30, 2017

Argh, I figured out why my User model was being loaded before Rolify was configured.

I'm using the simple_token_authentication gem, so I added this line to my ApplicationController:

acts_as_token_authentication_handler_for User

And my ApplicationController was being loaded at the bottom of my pundit initializer:

ApplicationController.send :include, PunditHelper

I added an underscore to move the rolify initializer to the top (config/initializers/rolify.rb => config/initializers/_rolify.rb), and this fixed the error.

@texpert
Copy link

texpert commented Jun 30, 2017

Have you added rolify to User model?

Also, to not load all the users, it is better to do it like this:

User.where(admin: true).each do |user|
  user.add_role :admin
end

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

2 participants