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

NoMethodError: undefined method `cast' for nil:NilClass after set value to field #53

Open
havran opened this issue May 24, 2017 · 3 comments

Comments

@havran
Copy link

havran commented May 24, 2017

Hello. Thanks for great gem!

I have weird problem in my production app.

If i try set value for field url in new or stored model, i always get NoMethodError: undefined method `cast' for nil:NilClass - but only for one field from all typed_Store defined fields.

Rails version is 5.x

In development mode works all ok.

module Space
  module ProjectItems
    class Page < ::Space::ProjectItem
      ...
      typed_store :data, coder: JsonCoder do |d|
        d.string  :valid_for_region,  array: true, default: []
        d.string  :category,                       default: nil
        d.string  :tag,               array: true, default: []
        d.string  :hashtag,                        default: nil
        d.string  :url,                            default: nil   # URL
      end
      ...
    end
  end
end
irb(main):044:0*  p = Space::ProjectItems::Page.new
=> #<Space::ProjectItems::Page id: nil, project_id: nil, item_type: "page", title: nil, description: nil, public: false, valid_from: nil, valid_to: nil, image_data: nil, data_location: {"lat"=>nil, "lon"=>nil, "zoom"=>nil, "formatted_address"=>nil}, data_zones: {"zones"=>[], "use_location_from_zones"=>false}, data: {"valid_for_region"=>[], "category"=>nil, "tag"=>[], "hashtag"=>nil, "url"=>nil}, created_at: nil, updated_at: nil, code: nil>
irb(main):045:0> p.data
=> {"valid_for_region"=>[], "category"=>nil, "tag"=>[], "hashtag"=>nil, "url"=>nil}
irb(main):046:0> p.category = 'a'
=> "a"
irb(main):047:0> p.hashtag = 'b'
=> "b"
irb(main):048:0> p.url = 'c'
NoMethodError: undefined method `cast' for nil:NilClass
        from /home/deployer/uidis/shared/bundle/ruby/2.3.0/gems/activerecord-typedstore-1.1.1/lib/active_record/typed_store/extension.rb:74:in `write_store_attribute'
        from /home/deployer/uidis/shared/bundle/ruby/2.3.0/gems/activerecord-5.0.3/lib/active_record/store.rb:91:in `block (3 levels) in store_accessor'
        from (irb):48
        from /home/deployer/uidis/shared/bundle/ruby/2.3.0/gems/railties-5.0.3/lib/rails/commands/console.rb:65:in `start'
        from /home/deployer/uidis/shared/bundle/ruby/2.3.0/gems/railties-5.0.3/lib/rails/commands/console_helper.rb:9:in `start'
        from /home/deployer/uidis/shared/bundle/ruby/2.3.0/gems/railties-5.0.3/lib/rails/commands/commands_tasks.rb:78:in `console'
        from /home/deployer/uidis/shared/bundle/ruby/2.3.0/gems/railties-5.0.3/lib/rails/commands/commands_tasks.rb:49:in `run_command!'
        from /home/deployer/uidis/shared/bundle/ruby/2.3.0/gems/railties-5.0.3/lib/rails/commands.rb:18:in `<top (required)>'
        from bin/rails:9:in `require'
        from bin/rails:9:in `<main>'
@havran
Copy link
Author

havran commented May 25, 2017

I try refactor my code. Before model Page is inherited from base model ProjectItems (models shared same database table, but i want different fields in store on every model). Now i have common model settings in concern and problem with set value on fields disappear.

I am still curious with this but i think this is burried too deep for my knowledge :-/

@byroot
Copy link
Owner

byroot commented May 25, 2017

Could you try reproduce the issue with a minimal app?

@ametalon
Copy link

I have the same problem which present itself only when model inheritance is used and descendant defines it's own typed_store. This has an unexpected effect of overriding typed_store value for same store_attribute for all class hierarchy and ancestors in particular.

For example this code results in all animals having gills:

class Animal < ApplicationRecord
  typed_store :data do |d|
    d.integer :ears_count, default: 2
  end
end

class Fish < Animal
  typed_store :data do |d|
    d.boolean :has_gills, default: true
  end
end

Animal.new.has_gills 
# => true
Animal.new.ears_count
# NoMethodError: undefined method `ears_count'

Desired behaviour for me is this:

class Animal < ApplicationRecord
  typed_store :data do |d|
    d.integer :ears_count, default: 2
  end
end

class Bear < Animal
end

class Fish < Animal
  typed_store :data do |d|
    d.boolean :has_gills, default: true
  end
end

Animal.new.ears_count
# => 2
Animal.new.has_gills 
# NoMethodError: undefined method `has_gills'

Bear.new.ears_count
# => 2
Bear.new.has_gills
# NoMethodError: undefined method `has_gills'

Fish.new.has_gills 
# => true
Fish.new.ears_count
# NoMethodError: undefined method `ears_count'

There are one possible solution in previous commit. What are your thoughts?

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