Ruby-on-rails – TypeError: can’t cast Array to string

nokogirirake-taskrubyruby-on-rails

I'm getting this error when trying to run a rake task using Nokogiri.

This is the code.

namespace :tops do
  desc "Get Tops Description"
  task get_description: :environment do
  require 'nokogiri'
  require 'open-uri'

 doc = Nokogiri::HTML(open("http://ceratoboutique.com/collections/tops"))

  price = Array.new 
  items = Array.new
  brands = Array.new
  sale_price = Array.new
  image = Array.new
  item_url = Array.new

  price = doc.xpath("//del").collect {|node| node.text.strip}
  items = doc.xpath("//div/a/h4").collect {|node| node.text.strip}
  brands = doc.xpath("//span[contains(@class,'vendor')]").collect {|node| node.text.strip}
  sale_price = doc.xpath("//span[contains(@class, 'price')]/text()").collect {|node| node.text.strip}
  image = doc.xpath("/div/a/img/@src").collect {|node| node.text.strip}
  item_url = doc.css('div.details a').map { |link| link['href'] }.collect 

  price.each do |prices|
      Tops.create(description: price)
    end
  end
end

This is the full error.

Rake aborted! TypeError: can't cast Array to string
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/abstract/quoting.rb:76:in type_cast'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/sqlite3_adapter.rb:261:in
type_cast'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/sqlite3_adapter.rb:295:in block in exec_query'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/sqlite3_adapter.rb:294:in
map'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/sqlite3_adapter.rb:294:in exec_query'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/abstract/database_statements.rb:68:in
exec_insert'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/abstract/database_statements.rb:95:in
insert'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/abstract/query_cache.rb:14:in
insert'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/relation.rb:64:in
insert'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/persistence.rb:502:in
_create_record'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/attribute_methods/dirty.rb:87:in
_create_record'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/callbacks.rb:306:in
block in _create_record'
/Library/Ruby/Gems/2.0.0/gems/activesupport-4.1.5/lib/active_support/callbacks.rb:82:in
run_callbacks'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/callbacks.rb:306:in
_create_record'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/timestamp.rb:57:in
_create_record'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/persistence.rb:482:in
create_or_update'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/callbacks.rb:302:in
block in create_or_update'
/Library/Ruby/Gems/2.0.0/gems/activesupport-4.1.5/lib/active_support/callbacks.rb:82:in
run_callbacks'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/callbacks.rb:302:in
create_or_update'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/persistence.rb:103:in
save'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/validations.rb:51:in
save'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/attribute_methods/dirty.rb:21:in
save'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/transactions.rb:268:in block (2 levels) in save'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/transactions.rb:329:in
block in with_transaction_returning_status'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/abstract/database_statements.rb:201:in
block in transaction'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/abstract/database_statements.rb:209:in
within_new_transaction'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/connection_adapters/abstract/database_statements.rb:201:in
transaction'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/transactions.rb:208:in
transaction'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/transactions.rb:326:in with_transaction_returning_status'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/transactions.rb:268:in
block in save'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/transactions.rb:283:in rollback_active_record_state!'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/transactions.rb:267:in
save'
/Library/Ruby/Gems/2.0.0/gems/activerecord-4.1.5/lib/active_record/persistence.rb:34:in
create' /Users/Kcummings/Sites/rvm_tests/lib/tasks/tops.rake:24:in
block (3 levels) in '
/Users/Kcummings/Sites/rvm_tests/lib/tasks/tops.rake:23:in each'
/Users/Kcummings/Sites/rvm_tests/lib/tasks/tops.rake:23:in
block (2
levels) in '
/Library/Ruby/Gems/2.0.0/gems/rake-10.3.2/lib/rake/task.rb:240:in
call'
/Library/Ruby/Gems/2.0.0/gems/rake-10.3.2/lib/rake/task.rb:240:in
block in execute'
/Library/Ruby/Gems/2.0.0/gems/rake-10.3.2/lib/rake/task.rb:235:in
each'
/Library/Ruby/Gems/2.0.0/gems/rake-10.3.2/lib/rake/task.rb:235:in
execute'
/Library/Ruby/Gems/2.0.0/gems/rake-10.3.2/lib/rake/task.rb:179:in
block in invoke_with_call_chain'
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/monitor.rb:211:in
mon_synchronize'
/Library/Ruby/Gems/2.0.0/gems/rake-10.3.2/lib/rake/task.rb:172:in
invoke_with_call_chain'
/Library/Ruby/Gems/2.0.0/gems/rake-10.3.2/lib/rake/task.rb:165:in
invoke'
/Library/Ruby/Gems/2.0.0/gems/rake-10.3.2/lib/rake/application.rb:150:in
invoke_task'
/Library/Ruby/Gems/2.0.0/gems/rake-10.3.2/lib/rake/application.rb:106:in
block (2 levels) in top_level'
/Library/Ruby/Gems/2.0.0/gems/rake-10.3.2/lib/rake/application.rb:106:in
each'
/Library/Ruby/Gems/2.0.0/gems/rake-10.3.2/lib/rake/application.rb:106:in
block in top_level'
/Library/Ruby/Gems/2.0.0/gems/rake-10.3.2/lib/rake/application.rb:115:in
run_with_threads'
/Library/Ruby/Gems/2.0.0/gems/rake-10.3.2/lib/rake/application.rb:100:in
top_level'
/Library/Ruby/Gems/2.0.0/gems/rake-10.3.2/lib/rake/application.rb:78:in
block in run'
/Library/Ruby/Gems/2.0.0/gems/rake-10.3.2/lib/rake/application.rb:176:in
standard_exception_handling'
/Library/Ruby/Gems/2.0.0/gems/rake-10.3.2/lib/rake/application.rb:75:in
run' /Library/Ruby/Gems/2.0.0/gems/rake-10.3.2/bin/rake:33:in' /usr/bin/rake:23:in load' /usr/bin/rake:23:in'

Edit: TOPS TABLE SCHEMA

    ActiveRecord::Schema.define(version: 20140824150641) do

      create_table "tops", force: true do |t|
        t.string   "brand"
        t.string   "description"
        t.string   "image"
        t.decimal  "price"
        t.datetime "created_at"
        t.datetime "updated_at"
        t.string   "url"
      end
end

Best Answer

Seems that you have description field in table tops as 'varchar' or string, however you are trying to store array in it.

You need to change datatype of description field to text and then serialize the value before trying to store it.

Generate new migration file and run it, On your terminal:

rails g migration change_desc_in_my_tops

As you are using Rails 4, add following code in your migration file:

class ChangeDescInTops < ActiveRecord::Migration
  def up
    change_column :tops, :description, :text
  end

  def down
    change_column :tops, :description, :string
  end
end

Now run migration:

rake db:migrate

Update your tops model as:

class Tops < ActiveModel::Base
  serialize :description, Array
  ...
  ...
end

Now try to run your rake task. Hope, it will help you.

NOTE: You should use singular model names. Your Tops model could be Top. It avoids confusion while using associations and it follows convention.

Related Topic