Hobo / hobo

The web app builder for Rails (moved from tablatom/hobo)
http://hobocentral.net
103 stars 39 forks source link

Regression: NoMethodError - undefined method `validate' for "male":String #167

Closed haslinger closed 8 years ago

haslinger commented 9 years ago

I just updated to the latest version here on master and now I get the error above for, when I try to save a user, that has

  Gender = HoboFields::Types::EnumString.for(:male, :female, :no_info)

  fields do
    gender           User::Gender
    ...
  end

Top of the stacktrace is

   () home/stefan/.rvm/gems/ruby-2.1.5/bundler/gems/hobo-e1dcb2ba159b/hobo_fields/lib/hobo_fields/model.rb:163:in `block in add_validations_for_field'
  activesupport (4.0.13) lib/active_support/callbacks.rb:417:in `_run__706463081247968266__validate__callbacks'
  activesupport (4.0.13) lib/active_support/callbacks.rb:80:in `run_callbacks'
  activemodel (4.0.13) lib/active_model/validations.rb:373:in `run_validations!'
  activemodel (4.0.13) lib/active_model/validations/callbacks.rb:106:in `block in run_validations!'
  activesupport (4.0.13) lib/active_support/callbacks.rb:373:in `_run__706463081247968266__validation__callbacks'
  activesupport (4.0.13) lib/active_support/callbacks.rb:80:in `run_callbacks'
  activemodel (4.0.13) lib/active_model/validations/callbacks.rb:106:in `run_validations!'
  activemodel (4.0.13) lib/active_model/validations.rb:314:in `valid?'
  activerecord (4.0.13) lib/active_record/validations.rb:70:in `valid?'
  (eval):6:in `valid?'

To check, if this is a regression, I switched back to hobo 2.1.1 and I'm fine again.

iox commented 9 years ago

Hi Stefan,

I just tested this with the latest master, and I have been unable to reproduce. I have:

Can you give me a bit more information to reproduce the error? Maybe it happens in a different user form?

Thanks, Ignacio

haslinger commented 9 years ago

Hi Ignacio,

thanks for your feedback and effort. I can provide a lot more info and it gets stranger and stranger ...

I saw the error when saving from a test, but I can reproduce it from a form the edit form as well. On that edit-form the dropdown is broken and shows only the string value (that's probably connected to the issue).

But I know more: The issue is easiest to reproduce in the console: Up to now I was able to update attributes by handing over strings to Enums and Email Hobo Types:

 user = User.first
 => #<User id: 6, ... I'm omitting the params here ... > 
2.1.5 :009 > user.gender = "female"
 => "female" 
2.1.5 :010 > user.save
 => true 
2.1.5 :011 > user.gender
 => "female" 

With the master branch that would fail:

2.1.5 :001 > user = User.first
 => #<User id: 6, surname: "Haslinger", email_address: "stefan.haslinger@mittenin.at", administrator: true, created_at: "2014-07-17 18:31:16", updated_at: "2015-08-16 14:45:12", state: "active", key_timestamp: nil, legacy_id: 633, sales: true, last_login_at: "2015-08-16 13:58:39", login_count: 372, logged_in: true, gtc_confirmed_at: nil, gtc_version_of: nil, sales_manager: true, locale: "de", gender: "female", title: "Mag.", first_name: "Stefan", contentmanager: true, productmanager: true, editor: "wysiwyg", waiting: false> 
2.1.5 :002 > user.gender = "female"
 => "female" 
2.1.5 :003 > user.save
NoMethodError: undefined method `validate' for "female":String
    from /home/stefan/.rvm/gems/ruby-2.1.5/bundler/gems/hobo-e1dcb2ba159b/hobo_fields/lib/hobo_fields/model.rb:163:in `block in add_validations_for_field'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activesupport-4.0.13/lib/active_support/callbacks.rb:417:in `_run__1016291566883766863__validate__callbacks'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activesupport-4.0.13/lib/active_support/callbacks.rb:80:in `run_callbacks'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activemodel-4.0.13/lib/active_model/validations.rb:373:in `run_validations!'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activemodel-4.0.13/lib/active_model/validations/callbacks.rb:106:in `block in run_validations!'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activesupport-4.0.13/lib/active_support/callbacks.rb:373:in `_run__1016291566883766863__validation__callbacks'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activesupport-4.0.13/lib/active_support/callbacks.rb:80:in `run_callbacks'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activemodel-4.0.13/lib/active_model/validations/callbacks.rb:106:in `run_validations!'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activemodel-4.0.13/lib/active_model/validations.rb:314:in `valid?'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activerecord-4.0.13/lib/active_record/validations.rb:70:in `valid?'
    from (eval):6:in `valid?'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activerecord-4.0.13/lib/active_record/validations.rb:77:in `perform_validations'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activerecord-4.0.13/lib/active_record/validations.rb:51:in `save'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activerecord-4.0.13/lib/active_record/attribute_methods/dirty.rb:32:in `save'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activerecord-4.0.13/lib/active_record/transactions.rb:270:in `block (2 levels) in save'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activerecord-4.0.13/lib/active_record/transactions.rb:330:in `block in with_transaction_returning_status'
... 8 levels...
    from (irb):3
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/railties-4.0.13/lib/rails/commands/console.rb:90:in `start'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/railties-4.0.13/lib/rails/commands/console.rb:9:in `start'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/railties-4.0.13/lib/rails/commands.rb:62:in `<top (required)>'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activesupport-4.0.13/lib/active_support/dependencies.rb:229:in `require'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activesupport-4.0.13/lib/active_support/dependencies.rb:229:in `block in require'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activesupport-4.0.13/lib/active_support/dependencies.rb:214:in `load_dependency'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activesupport-4.0.13/lib/active_support/dependencies.rb:229:in `require'
    from /media/Storage/rails/mercator/bin/rails:10:in `<top (required)>'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activesupport-4.0.13/lib/active_support/dependencies.rb:223:in `load'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activesupport-4.0.13/lib/active_support/dependencies.rb:223:in `block in load'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activesupport-4.0.13/lib/active_support/dependencies.rb:214:in `load_dependency'
    from /home/stefan/.rvm/gems/ruby-2.1.5/gems/activesupport-4.0.13/lib/active_support/dependencies.rb:223:in `load'
    from /home/stefan/.rvm/rubies/ruby-2.1.5/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /home/stefan/.rvm/rubies/ruby-2.1.5/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from -e:1:in `<main>'2.1.5 :004 > 

and now I have to provide a proper Enum: user.gender = User::Gender::FEMALE and still get NoMethodError: undefined methodvalidate' for "stefan.haslinger@mittenin.at":String` because suddenly I have to "reprovide" all special hobo attributes to be able to save the record again.

user.email_address = HoboFields::Types::EmailAddress.new("stefan.haslinger@mittenin.at")
user.editor = User::EditorType::WYSIWYG
user.save

So strings are not accepted for the attributes which are Hobo::Field::.... any more. And I promise: The only thing I change is the Gemfile where I switch gem "hobo", "= 2.1.1" for gem 'hobo', :git => 'https://github.com/Hobo/hobo.git' and switching back (and bundle install) and everything is fine again.

And the strangest thing: it only happens in the User Model, BillingAddress has the same kind of gender - Enum and works as ever....

Warm regards, Stefan

haslinger commented 9 years ago

I just learned about git bisect and could drill it down. The first commit where the issue comes up is 57f0a8462a4afc650c118bab553c4ea1a78e4f56 . Does this make any more sense?

iox commented 8 years ago

Hi Stefan,

Thanks a lot for all of the details, they are really helpful! I have tried reproducing it again, but I was unsuccessful!

vagrant@precise-base:/vagrant/ruby21tests/issue_167_regression$ rails c
Loading development environment (Rails 4.0.13)
irb(main):001:0> user = User.first
  User Load (0.7ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
=> #<User id: 1, crypted_password: "f539d31ee9b4b4cb9e3127c124a76a3c45da7f70", salt: "4de25ed0027d1b3b80ec114d2cc964a3bd32b064", remember_token: nil, remember_token_expires_at: nil, name: "Ignacio", email_address: "ignacio@ihuerta.net", administrator: true, created_at: "2015-03-11 17:51:50", updated_at: "2015-08-16 10:31:49", state: "active", key_timestamp: nil, gender: "no_info">
irb(main):002:0> user.gender
=> "no_info"
irb(main):003:0> user.gender = 'male'
=> "male"
irb(main):004:0> user.save
   (0.2ms)  begin transaction
  User Exists (0.1ms)  SELECT 1 AS one FROM "users" WHERE ("users"."name" = 'Ignacio' AND "users"."id" != 1) LIMIT 1
  User Exists (0.1ms)  SELECT 1 AS one FROM "users" WHERE (LOWER("users"."email_address") = LOWER('ignacio@ihuerta.net') AND "users"."id" != 1) LIMIT 1
  SQL (2.6ms)  UPDATE "users" SET "gender" = ?, "updated_at" = ? WHERE "users"."id" = 1  [["gender", "male"], ["updated_at", Sat, 12 Sep 2015 12:16:16 UTC +00:00]]
   (10.3ms)  commit transaction
=> true
irb(main):005:0> user.gender
=> "male"

Your example works in my console, using the latest Hobo master. What exact Ruby version are you using? I just tested it with Ruby 2.1.5p273.

Warm regards, Ignacio

haslinger commented 8 years ago

Hi Ignacio!

Thanks for your efforts and congratulations on the 4.2 support! My Ruby version is ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-linux] so it's the same as yours. I will try to go the other way round tomorrow: copy my big app and strip down stuff until it works. Then I should be able to find the dependency or at least to create a small app with the issue i can upload.

Ciao, Stefan

haslinger commented 8 years ago

Hurray!

I got it: I had defined the constant

JOBUSER = self.find_by(surname: "Job User")

right before the fields-block. Moving that down after the fields-block fixes it.

My app now already runs on hobo 2.2.3 / rails 4.2.4 in development, tomorrow I will run my test suite. :-)

Cheers and warm greetings from Vienna, Stefan

iox commented 8 years ago

Nice! I'm glad you found it. And I'm impressed that you had time to update your app already!

Please ignore my email from this morning with the attached test app, I had not read the latest Github notification :).