Я пытаюсь загрузить начальные данные в мое приложение Rails из файла CSV. Первоначально я установил гем quickcsv, только чтобы выяснить, что quickcsv устарел в пользу библиотеки CSV, начиная с ruby 1.9. Поэтому я переключился на CSV после получения очень полезной ошибки, в которой говорилось, что нужно переключаться.
Теперь, однако, я получаю странное явление, когда при загрузке данных все выглядит нормально, но я не могу выполнить запрос к строковым полям. Строковые поля заполняются, как представляется, правильными строками, но я не могу получить к ним доступ. Я могу запросить любое из числовых полей, и результаты будут возвращаться, но не строковые поля. Я пытался играть с разделителем для цитат, но безрезультатно. Я даже вычеркнул все кавычки из моего CSV-файла, но все равно не смог запросить строковые поля. Ниже приведен мой код, а также некоторые примеры запросов и возвратов из консоли Rails.
# seeds.rb
# ================
require 'csv'
directory = "db/init_data/"
file_name = "players.seed"
path_to_file = directory + file_name
puts 'Loading Player records'
# Pre-load All Player records
n=0
CSV.foreach(path_to_file) do |row|
Player.create! :first_name => row[1], :last_name => row[2], :position_id => row[5], :weight => row[6], :height => row[7], :year => row[8], :home_state => row[9], :home_town => row[10], :home_country => row[11], :high_school_id => row[12], :name => row[13]
n=n+1
end
Вот первые две записи из моего начального файла.
# players.seed
"1","Allerik","Freeman","2011-10-11 22:21:21.230247","2011-10-11 22:21:21.230247","2","210","76","2013","NC","Charlotte","USA","1","Allerik Freeman"
"2","Kasey","Hill","2011-10-11 22:21:21.262409","2011-10-11 22:21:21.262409","1","170","73","2013","FL","Eustis","USA","2","Kasey Hill"
Это то, что я получаю, когда вхожу в консоль рельсов. Это прекрасно работает, если я хочу запросить число, например, год.
ruby-1.9.2-p290 :002 > Player.find_all_by_year(2013)
Player Load (0.7ms) SELECT "players".* FROM "players" WHERE "players"."year" = 2013
=> [#<Player id: 1, first_name: "Allerik", last_name: "Freeman", created_at: "2011-10-12 20:52:16", updated_at: "2011-10-12 20:52:16", position_id: 2, weight: 210, height: 76, year: 2013, home_state: "NC", home_town: "Charlotte", home_country: "USA", high_school_id: 1, name: "Allerik Freeman">, #<Player id: 2, first_name: "Kasey", last_name: "Hill", created_at: "2011-10-12 20:52:16", updated_at: "2011-10-12 20:52:16", position_id: 1, weight: 170, height: 72, year: 2013, home_state: "FL", home_town: "Eustis", home_country: "USA", high_school_id: 2, name: "Kasey Hill">]
Но если я попытаюсь сделать запрос, скажем, по фамилии, я ничего не получу, даже если он покажет, что фамилия присутствует в предыдущем запросе.
ruby-1.9.2-p290 :004 > Player.find_all_by_last_name("Freeman")
Player Load (0.3ms) SELECT "players".* FROM "players" WHERE "players"."last_name" = 'Freeman'
=> []
Единственный способ заставить его работать - это поместить его в дополнительный набор двойных кавычек (экранированный), используя нотацию хеш-переменной, которая переводила все мои строковые записи в базу данных в кавычках, затем я использовал удаление Команда, чтобы удалить цитаты обратно.
n=0
CSV.foreach(path_to_file) do |row|
Player.create! :first_name => "\"#{row[1]}\"", :last_name => "\"#{row[2]}\"", :position_id => row[5], :weight => row[6], :height => row[7], :year => row[8], :home_state => "\"#{row[9]}\"", :home_town => "\"#{row[10]}\"", :home_country => "\"#{row[11]}\"", :high_school_id => row[12], :name => "\"#{row[13]}\""
n=n+1
end
puts "There\'s too many playas to hate, we just loaded #{n} of \'em"
@players = Player.all
@players.each do |player|
fname = player.first_name
player.first_name = fname.delete("\"")
lname = player.last_name
player.last_name = lname.delete("\"")
pcity = player.home_town
player.home_town = pcity.delete("\"")
pst = player.home_state
player.home_state = pst.delete("\"")
pcountry = player.home_country
player.home_country = pcountry.delete("\"")
pname = player.name
player.name = pname.delete("\"")
player.save!
end
Тогда я мог бы запросить данные строки.
ruby-1.9.2-p290 :005 > Player.find_all_by_last_name("Freeman")
Player Load (0.6ms) SELECT "players".* FROM "players" WHERE "players"."last_name" = 'Freeman'
=> [#<Player id: 1, first_name: "Allerik", last_name: "Freeman", created_at: "2011-10-12 20:52:16", updated_at: "2011-10-12 20:52:16", position_id: 2, weight: 210, height: 76, year: 2013, home_state: "NC", home_town: "Charlotte", home_country: "USA", high_school_id: 1, name: "Allerik Freeman">, #<Player id: 59, first_name: "Austin", last_name: "Freeman", created_at: "2011-10-12 20:55:16", updated_at: "2011-10-12 20:55:16", position_id: 2, weight: 210, height: 76, year: 2007, home_state: "MD", home_town: "Hyattsville", home_country: "USA", high_school_id: nil, name: "Austin Freeman">]
Очевидно, что это не предпочтительный метод, так как он удвоил время моей загрузки, но я был честен в своем уме.
Любая помощь будет принята с благодарностью.
Как я и просил, я добавил schema.rb
# schema.rb
# ===================
# encoding: UTF-8
# ...
ActiveRecord::Schema.define(:version => 20111007214728) do
#...
create_table "players", :force => true do |t|
t.string "first_name"
t.string "last_name"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "position_id"
t.integer "weight"
t.integer "height"
t.integer "year"
t.string "home_state"
t.string "home_town"
t.string "home_country"
t.integer "high_school_id"
t.string "name"
end
# ...
end
Вот скриншоты базы данных, просматриваемые моим браузером баз данных SQLite по запросу.
![View of Player Table: Looks normal right?](https://i.stack.imgur.com/mUbFI.png)
![No Rows Returned when querying a string field](https://i.stack.imgur.com/iraIL.png)
Похоже, здесь есть похожая проблема на форумах ruby , и что это, вероятно, связано с кодировкой, но мне нужно будет провести гораздо больше исследований по кодированию, чтобы понять это.