Search code examples
ruby-on-railshstore

Rails HStore issue - TypeError: can't cast Hash


Trying to follow this tutorial for setting up an hstore. I've went through and added a preferences hstore to the User model and it all works correctly. Now I've added an exercises hstore to a different model, and this is what I get:

irb(main):128:0* workout = Workout.new
=> #<Workout id: nil, user_id: nil, created_at: nil, updated_at: nil, exercises: nil>
irb(main):129:0> workout.exercises = {
irb(main):130:1* lunges: "10"
irb(main):131:1> }
=> {:lunges=>"10"}
irb(main):132:0> workout.save!
   (0.2ms)  begin transaction
   (1.5ms)  rollback transaction
TypeError: can't cast Hash to 
    from /usr/local/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract/quoting.rb:34:in `rescue in type_cast'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract/quoting.rb:23:in `type_cast'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/connection_adapters/sqlite3_adapter.rb:294:in `block in exec_query'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/connection_adapters/sqlite3_adapter.rb:293:in `map'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/connection_adapters/sqlite3_adapter.rb:293:in `exec_query'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract/database_statements.rb:76:in `exec_insert'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract/database_statements.rb:108:in `insert'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/connection_adapters/abstract/query_cache.rb:14:in `insert'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/relation.rb:64:in `insert'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/persistence.rb:521:in `_create_record'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/counter_cache.rb:139:in `_create_record'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/attribute_methods/dirty.rb:127:in `_create_record'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activerecord-4.2.0/lib/active_record/callbacks.rb:306:in `block in _create_record'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:88:in `call'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:88:in `_run_callbacks'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/callbacks.rb:734:in `_run_create_callbacks'
... 24 levels...
    from /usr/local/lib/ruby/gems/2.2.0/gems/railties-4.2.0/lib/rails/commands/console.rb:9:in `start'
    from /usr/local/lib/ruby/gems/2.2.0/gems/railties-4.2.0/lib/rails/commands/commands_tasks.rb:68:in `console'
    from /usr/local/lib/ruby/gems/2.2.0/gems/railties-4.2.0/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
    from /usr/local/lib/ruby/gems/2.2.0/gems/railties-4.2.0/lib/rails/commands.rb:17:in `<top (required)>'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:274:in `require'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:274:in `block in require'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:240:in `load_dependency'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:274:in `require'
    from /Users/nomad/Documents/milonos/bin/rails:8:in `<top (required)>'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `load'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `block in load'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:240:in `load_dependency'
    from /usr/local/lib/ruby/gems/2.2.0/gems/activesupport-4.2.0/lib/active_support/dependencies.rb:268:in `load'
    from /usr/local/Cellar/ruby/2.2.2/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from /usr/local/Cellar/ruby/2.2.2/lib/ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
    from -e:1:in `<main>'irb(main):133:0> 

My migration for creating the Workout model is:

class CreateWorkouts < ActiveRecord::Migration
  def change
    create_table :workouts do |t|
      t.references :user, index: true

      t.timestamps null: false
    end
    add_foreign_key :workouts, :users
  end
end

And the migration for adding the hstore:

class AddExercisesToWorkouts < ActiveRecord::Migration
  def change
    enable_extension "hstore"
    add_column :workouts, :exercises, :hstore
    add_index :workouts, :exercises, using: :gist
  end
end

And my model:

class Workout < ActiveRecord::Base
  belongs_to :user
  store_accessor :exercises
end

When doing user = User.new and adding hash settings just as above to the preferences hstore, everything seems to work. What am I missing here ?


Solution

  • What I ended up doing was installing postgres and switching from sqlite to it. Then I did rake db:drop db:create db:migrate db:seed, and all the migrations went through. Changed databases.yml to:

    # PostgreSQL. Versions 8.2 and up are supported.
    #
    # Install the pg driver:
    #   gem install pg
    # On OS X with Homebrew:
    #   gem install pg -- --with-pg-config=/usr/local/bin/pg_config
    # On OS X with MacPorts:
    #   gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config
    # On Windows:
    #   gem install pg
    #       Choose the win32 build.
    #       Install PostgreSQL and put its /bin directory on your path.
    #
    # Configure Using Gemfile
    # gem 'pg'
    #
    development:
      adapter: postgresql
      encoding: unicode
      database: appname_development
      pool: 5
      username: username
      password:
      timeout: 5000
    
      # Connect on a TCP socket. Omitted by default since the client uses a
      # domain socket that doesn't need configuration. Windows does not have
      # domain sockets, so uncomment these lines.
      #host: localhost
    
      # The TCP port the server listens on. Defaults to 5432.
      # If your server runs on a different port number, change accordingly.
      #port: 5432
    
      # Schema search path. The server defaults to $user,public
      #schema_search_path: myapp,sharedapp,public
    
      # Minimum log levels, in increasing order:
      #   debug5, debug4, debug3, debug2, debug1,
      #   log, notice, warning, error, fatal, and panic
      # Defaults to warning.
      #min_messages: notice
    
    # Warning: The database defined as "test" will be erased and
    # re-generated from your development database when you run "rake".
    # Do not set this db to the same as development or production.
    test:
      adapter: postgresql
      encoding: unicode
      database: appname_test
      pool: 5
      username: username
      password:
      timeout: 5000