Error message when running Rake command in Rails app - ruby

I'm trying to create posts in my Rails app by pulling data from a CSV file.
When I try to run a Rake command, I get the error message below. What's wrong with this code?
SEED.RAKE FILE
require 'csv'
namespace :csv do
desc "Import CSV Data for Michelin Star Restaurants"
task :post => :environment do
csv_file_path = 'db/data.csv'
CSV.foreach(csv_file_path) do |row|
Post.create({
:name => row[1],
:address => row[2],
:city => row[3],
:michelin_status => row[4],
:website => row[5],
:phone => row[6],
:longitude => row[7],
:latitude => row[8],
:inthenews => row[9],
:google_reviews => row[10],
})
end
end
end
ERROR MESSAGE FROM CONSOLE
Faisals-Air:dinner fkhalid2008$ rake csv:post
rake aborted!
ArgumentError: invalid byte sequence in UTF-8
/Users/fkhalid2008/dinner/lib/tasks/seed.rake:11:in `block (2 levels) in <top (required)>'
/Users/fkhalid2008/.rvm/gems/ruby-2.2.0/bin/ruby_executable_hooks:15:in `eval'
/Users/fkhalid2008/.rvm/gems/ruby-2.2.0/bin/ruby_executable_hooks:15:in `<main>'
Tasks: TOP => csv:post
(See full trace by running task with --trace)
DB MIGRATE FILE
class CreatePosts < ActiveRecord::Migration
def change
create_table :posts do |t|
t.string :name
t.string :inthenews
t.string :michelin_status
t.string :google_reviews
t.string :address
t.string :city
t.string :website
t.integer :phone
t.integer :longitude
t.integer :latitude
t.timestamps null: false
end
end
end
CSV FILE SCREENSHOT

This is because somewhere in your file there are some invalid bytes.
To avoid this issue, you can use scrub method like this:
CSV.foreach(csv_file_path) do |row|
Post.create({
:name => row[1].scrub,
:address => row[2].scrub,
:city => row[3].scrub,
:michelin_status => row[4].scrub,
:website => row[5].scrub,
:phone => row[6].scrub,
:longitude => row[7].scrub,
:latitude => row[8].scrub,
:inthenews => row[9].scrub,
:google_reviews => row[10].scrub,
})
end
Update
Try to specify the encoding type when you read the CSV file like this:
CSV.foreach(csv_file_path, "r:ISO-8859-1") do |row|
. . .
. . .
end

You can simply convert the original csv file to utf8 with nkf.
$ nkf -w --overwrite db/data.csv

Related

Creating an ActiveRecord database for a webcrawler. Having issues adding index

I'm working on a three part program for a webcrawler program for school. My first step is to just create the database using activerecord and knowing that it will be queried later using sqlite3. The database actually does get created with my current program. However, it errors out when gets to "add_index". I'm not great with databases in general so guidance is appreciated.
Before I put in my code the error is:
crawler_create.rb:23: syntax error, unexpected ',', expecting ')'
add_index (:pages,[:url], unique=> true)
Here's what I've come up with so far:
require 'active_record'
require 'sqlite3'
db=SQLite3::Database.new("crawler.db")
ActiveRecord::Base.establish_connection(adapter:'sqlite3',database:'crawler.db')
ActiveRecord::Schema.define do
create_table :pages do |t|
t.string :url, :null => false
t.string :title
t.string :content_type
t.date :last_modified
t.string :status
end
end
add_index (:pages,[:url], unique=> true)
ActiveRecord::Schema.define do
create_table :links do |t|
t.integer :from_page_id, :null => false
t.integer :to_page_id, :null => false
end
end
add_index(:links,[:from_page_id,:pages_id], :unique =>true)
ActiveRecord::Schema.define do
add_foreign_key :from_page_id, :pages_id
add_foreign_key :to_page_id,:pages_id
end
It looks like you got a simple syntax error here:
add_index (:pages, [:url], unique: true)
I'd suggest that you use a consistent hash syntax, either using hash rockets => or the newer syntax unique: true.

friendly_id 4.0.8 with rails 3.0.1 rails generate friendly_id not working?

I am using friendly_id 4.0.8 with rails 3.0.1. I want to use the history feature.
When I type the command rails generate friendly_id, it fails with the following error message:
[WARNING] Could not load generator "generators/friendly_id_generator". Error: ActiveRecord is not missing constant Migration!.
/usr/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/dependencies.rb:479:in `load_missing_constant'
/usr/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/dependencies.rb:183:in `rake_original_const_missing'
/usr/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/dependencies.rb:181:in `each'
/usr/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/dependencies.rb:181:in `rake_original_const_missing'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2503:in `const_missing'
/usr/lib/ruby/gems/1.8/gems/friendly_id-4.0.8/lib/generators/friendly_id_generator.rb:8
/usr/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/dependencies.rb:239:in `require'
/usr/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/dependencies.rb:239:in `require'
/usr/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/dependencies.rb:225:in `load_dependency'
/usr/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/dependencies.rb:591:in `new_constants_in'
/usr/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/dependencies.rb:225:in `load_dependency'
/usr/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/dependencies.
Is there some different syntax to make it work ?
I have got it working currently by manually generating a migration script with
rails generate migration create_friendly_id_slugs
Then replace the contents of the migration script with that from gems/friendly_id-4.0.8/lib/friendly_id/migration.rb as follows:
class CreateFriendlyIdSlugs < ActiveRecord::Migration
def self.up
create_table :friendly_id_slugs do |t|
t.string :slug, :null => false
t.integer :sluggable_id, :null => false
t.string :sluggable_type, :limit => 40
t.datetime :created_at
end
add_index :friendly_id_slugs, :sluggable_id
add_index :friendly_id_slugs, [:slug, :sluggable_type], :unique => true
add_index :friendly_id_slugs, :sluggable_type
end
def self.down
drop_table :friendly_id_slugs
end
end
Then run rake db:migrate

How to migrate correctly with sequel on Access 2007

When I migrate my application to Access 2007 with sequel library of Ruby. I get the errors as follows. Does anybody know how to migrate correctly? Thanks.
C:\ContractManagement>rackup
C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/adapters/ado.rb:63:
in `method_missing': WIN32OLERuntimeError: (in OLE method `Execute': ) (Sequel::
DatabaseError)
OLE error code:80040E14 in Microsoft Office Access Database Engine
Syntax error (missing operator) in query expression 'LIMIT 1 1'.
HRESULT error code:0x80020009
Exception occurred.
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/adapte
rs/ado.rb:63:in `block (2 levels) in execute'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/databa
se/logging.rb:28:in `log_yield'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/adapte
rs/ado.rb:63:in `block in execute'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/connec
tion_pool/threaded.rb:84:in `hold'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/databa
se/connecting.rb:226:in `synchronize'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/adapte
rs/ado.rb:61:in `execute'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/datase
t/actions.rb:541:in `execute'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/adapte
rs/ado.rb:97:in `fetch_rows'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/datase
t/actions.rb:123:in `each'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/datase
t/actions.rb:449:in `single_record'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/datase
t/actions.rb:457:in `single_value'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/datase
t/actions.rb:200:in `get'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/datase
t/actions.rb:133:in `empty?'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/extens
ions/migration.rb:499:in `schema_dataset'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/extens
ions/migration.rb:381:in `initialize'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/extens
ions/migration.rb:422:in `initialize'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/extens
ions/migration.rb:332:in `new'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/extens
ions/migration.rb:332:in `run'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/sequel-3.23.0/lib/sequel/extens
ions/migration.rb:316:in `apply'
from C:/ContractManagement/config.ru:12:in `block in <main>'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/rack-1.3.0/lib/rack/builder.rb:
51:in `instance_eval'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/rack-1.3.0/lib/rack/builder.rb:
51:in `initialize'
from C:/ContractManagement/config.ru:1:in `new'
from C:/ContractManagement/config.ru:1:in `<main>'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/rack-1.3.0/lib/rack/builder.rb:
40:in `eval'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/rack-1.3.0/lib/rack/builder.rb:
40:in `parse_file'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/rack-1.3.0/lib/rack/server.rb:2
00:in `app'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/rack-1.3.0/lib/rack/server.rb:3
01:in `wrapped_app'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/rack-1.3.0/lib/rack/server.rb:2
52:in `start'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/rack-1.3.0/lib/rack/server.rb:1
37:in `start'
from C:/Ruby192/lib/ruby/gems/1.9.1/gems/rack-1.3.0/bin/rackup:4:in `<to
p (required)>'
from C:/Ruby192/bin/rackup:19:in `load'
from C:/Ruby192/bin/rackup:19:in `<main>'
Here is the connection configuration.
DB = Sequel.ado(:conn_string=>'Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\ContractManagement1.accdb')
And here is the migration steps. All are passed on PostgreSQL 8.4.
Sequel.migration do
up do
create_table :people do
primary_key :id
String :name, :size => 20, :unique => true, :null => false
String :password, :size => 30, :null => false
String :role, :size => 20, :null => false
end
end
down do
drop_table :people
end
end
Sequel.migration do
up do
create_table :currencies do
primary_key :id
String :name, :size => 10, :null => false
end
end
down do
drop_table :currencies
end
end
Sequel.migration do
up do
create_table :statuses do
primary_key :id
String :name, :size => 10, :null => false
end
end
down do
drop_table :statuses
end
end
# encoding: utf-8
Sequel.migration do
up do
create_table :contracts do
primary_key :id
String :contract_id, :size => 36, :unique => true, :null => false
String :content, :size => 150
String :supplier, :size => 30
Date :created_on
Date :expired_on
BigDecimal :amount, :size => [10, 2], :null => false
Fixnum :debt_days
Fixnum :guarantee_period
String :order_id, :size => 50 # 订单号
String :supplier_contract_id, :size => 36
String :operator, :size => 30
foreign_key :currency_id, :currencies, :on_delete => :cascade, :on_update => :cascade, :null => false
foreign_key :status_id, :statuses, :on_delete => :cascade, :on_update => :cascade, :null => false
constraint(:min_amount) { amount >= 0.01 }
end
end
down do
drop_table :contracts
end
end
# encoding: utf-8
Sequel.migration do
up do
self[:currencies].insert(:name => "人民币")
self[:currencies].insert(:name => "欧元")
self[:currencies].insert(:name => "美元")
end
down do
self[:currencies].delete
end
end
# encoding: utf-8
Sequel.migration do
up do
self[:statuses].insert(:name => "执行中")
self[:statuses].insert(:name => "关闭")
self[:statuses].insert(:name => "作废")
end
down do
self[:statuses].delete
end
end
# encoding: utf-8
Sequel.migration do
up do
create_table :payments do
primary_key :id
BigDecimal :prepayment, :size => [10, 2], :default => 0 # 预付金额(元)
BigDecimal :offset_prepayment, :size => [10, 2], :default => 0 # 冲预付
BigDecimal :guarantee_price, :size => [10, 2], :default => 0 # 质保金
BigDecimal :request_amount, :size => [10, 2], :default => 0 # 申请付款额
foreign_key :contract_id, :contracts, :on_delete => :cascade, :on_update => :cascade
foreign_key :person_id, :people, :on_delete => :cascade, :on_update => :cascade
constraint(:offset_prepayment_is_not_greater_than_prepayment) { prepayment >= offset_prepayment } # offset_prepayment不能大于prepayment
end
end
down do
drop_table :payments
end
end
Sequel.migration do
up do
{"admin" => "Admin", "contract" => "ContractOperator", "payment" => "PaymentOperator", "report" => "ReportReviewer"}.each do |n, r|
self[:people].insert(:name => n, :password => n, :role => r)
end
self[:people].insert(:name => "payment1", :password => "payment1", :role => "PaymentOperator")
end
down do
self[:people].delete
end
end
I think you get this error message ...
OLE error code:80040E14 in Microsoft Office Access Database Engine
Syntax error (missing operator) in query expression 'LIMIT 1 1'.
... because Access SQL doesn't support LIMIT. See this reply to a related Stack Overflow question.
See whether you can use Access SQL TOP N as a substitute for LIMIT N.
SELECT TOP 1 m.id, m.paid_in_full, m.date_field
FROM MyTable AS m
ORDER BY m.date_field DESC;
This is fixed in the master branch of Sequel, version 3.24.0 (which will be released next week) will have the bugfix.

Why am I getting the error "undefined method `name' for" in a Formtastic / haml view where "name" is a property on the model?

This is probably something stupid, but I don't know nearly enough about rails & ruby to see it. I have the following schema & view but I am getting the error mentioned below. Business inherits from a Devise Account so thats where the email & password come from.
Any help would be greatly appreciated, thanks!
schema:
create_table "businesses", :force => true do |t|
t.string "name"
t.string "street"
t.string "city"
t.string "zip"
t.datetime "created_at"
t.datetime "updated_at"
end
View:
#registrationForm
-semantic_form_for(resource, :as => resource_name, :url=> registration_path(resource_name)) do |f|
=f.input :name
=f.input :email
=f.input :password
=f.input :password_confirmation
=f.buttons
Error:
undefined method 'name' for
<Business:0x000000052690f8 > Extracted source (around line #3):
Edit
Controller
class BusinessesController < Devise::RegistrationsController
respond_to :html
def new
super
#business = Business.new
end
end
Routes.rb
devise_for :accounts
devise_for :businesses, :controllers => { :registrations => "businesses" }
Model
class Business < Account
end
console after reloading schema
k = Business.new ( :name =>"test" )
^
(irb):1: syntax error, unexpected ')', expecting $end
from /home/chance/.rvm/gems/ruby-1.9.2-p180#global/gems/railties-3.0.5/lib/rails/commands/console.rb:44:in `start'
from /home/chance/.rvm/gems/ruby-1.9.2-p180#global/gems/railties-3.0.5/lib/rails/commands/console.rb:8:in `start'
from /home/chance/.rvm/gems/ruby-1.9.2-p180#global/gems/railties-3.0.5/lib/rails/commands.rb:23:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
You have a table named 'accounts' and a table named 'businesses'.
Account is being made by devise, and has all its attributes, and points to the 'accounts' table.
Business inherits from Account, and therefore is using Rails' STI (single table inheritance) features. It therefore points to the 'accounts' table as well.
If you were to have Business < ActiveRecord::Base it would point to your 'businesses' table. ActiveRecord's STI mechanism is very strange.
I think you need to think more about how you want your data model to work. Perhaps Business should belong_to :account and have an according :account_id.
Either that or you could add all the 'businesses' columns to the accounts table.
Try to load your schema again
rake db:schema:load

Sequel::Model: Where the methods like create_table come from?

I am trying to understand how Sequel works. The example below inherit from Sequel::Model and calls set_schema, create_table, etc.
I was trying to find the documentation for these methods, but no luck on the rdoc for Sequel::Model: http://sequel.rubyforge.org/rdoc/classes/Sequel/Model.html
Where are these methods coming from and how does Sequel::Model make them available?
class Task < Sequel::Model
set_schema do
primary_key :id
varchar :title, :unique => true, :empty => false
boolean :done, :default => false
end
create_table unless table_exists?
if empty?
create :title => 'Laundry'
create :title => 'Wash dishes'
end
end
They're defined in Sequel::Plugins::Schema::ClassMethods (lib/sequel/plugins/schema.rb) and included when you call plugin :schema in your model.
http://sequel.rubyforge.org/rdoc-plugins/classes/Sequel/Plugins/Schema/ClassMethods.html#M000110
http://sequel.rubyforge.org/rdoc/classes/Sequel/Model.html#M000130
The example in the question is incomplete and won't work unless a connection to a database is setup and the plugin :schema is called from the model.
irb(main):001:0> require "rubygems"
=> true
irb(main):002:0> require "sequel"
=> true
irb(main):003:0>
irb(main):004:0* # connect to an in-memory database
irb(main):005:0* DB = Sequel.sqlite
=> #<Sequel::SQLite::Database: "sqlite:/">
irb(main):006:0> class Task < Sequel::Model
irb(main):007:1> set_schema do
irb(main):008:2* primary_key :id
irb(main):009:2>
irb(main):010:2* varchar :title, :unique => true, :empty => false
irb(main):011:2> boolean :done, :default => false
irb(main):012:2> end
irb(main):013:1>
irb(main):014:1* create_table unless table_exists?
irb(main):015:1>
irb(main):016:1* if empty?
irb(main):017:2> create :title => 'Laundry'
irb(main):018:2> create :title => 'Wash dishes'
irb(main):019:2> end
irb(main):020:1> end
NoMethodError: undefined method `set_schema' for Task:Class
from (irb):7
irb(main):021:0> class Task < Sequel::Model
irb(main):022:1> plugin :schema
irb(main):023:1> set_schema do
irb(main):024:2* primary_key :id
irb(main):025:2>
irb(main):026:2* varchar :title, :unique => true, :empty => false
irb(main):027:2> boolean :done, :default => false
irb(main):028:2> end
irb(main):029:1>
irb(main):030:1* create_table unless table_exists?
irb(main):031:1>
irb(main):032:1* if empty?
irb(main):033:2> create :title => 'Laundry'
irb(main):034:2> create :title => 'Wash dishes'
irb(main):035:2> end
irb(main):036:1> end
=> #<Task #values={:title=>"Wash dishes", :done=>false, :id=>2}>
irb(main):037:0>

Resources