Rails 5.1
我的迁移文件:
class CreateFwExports < ActiveRecord::Migration[5.1]
def change
create_table :fw_exports, id: :string do |t|
t.string :screen_name, index: true, limit: 16
t.string :full_name, limit: 21
t.string :location
t.timestamps
end
end
end
在我的帮助文件中,我有以下方法:
def process_spreadsheet(number_of_rows, spreadsheet)
for i in 1..number_of_rows do
fw_export_record = FwExport.new(
:screen_name => spreadsheet[i][0].to_s,
:full_name => spreadsheet[i][1].to_s,
:location => spreadsheet[i][2].to_s,
)
fw_export_record.save
end
end
此方法的作用是接收电子表格CSV对象,并迭代数据,尝试将每一行保存到fw_exports表。
第一个数据行是:
xxxxxxxx,xxxxxxxxxx,"Nottingham, England"
我收到以下错误消息:
ActiveRecord::AssociationTypeMismatch (Location(#38400060) expected, got "Nottingham, England" which is an instance of String(#10657520)):
app/helpers/fw_exports_helper.rb:21:in `block in process_spreadsheet'
app/helpers/fw_exports_helper.rb:20:in `process_spreadsheet'
app/controllers/fw_exports_controller.rb:82:in `process_parsed_spreadsheet'
当我查看实际的MySQL表时,这是我得到的:
id Primary varchar(255) utf8mb4_unicode_ci No None
screen_name varchar(16) utf8mb4_unicode_ci Yes NULL
full_name varchar(21) utf8mb4_unicode_ci Yes NULL
location varchar(255) utf8mb4_unicode_ci Yes NULL
来自控制器:
def fw_export_params
params.require(:fw_export).permit(:screen_name, :full_name, :location)
end
id是通过关注部分
中定义的方法生成的知道我为什么收到错误消息?
在我的fw_exports.rb模型中,我有以下内容:
has_one :location
我有一个位置表(和模型),包含以下字段:
t.string :fw_exports_id, index: true
t.string :city
t.string :state
t.string :country
当我注释掉时,fw_exports.rb模型中的行:
# has_one :location
我停止了上面提到的错误,相反,我现在收到以下错误:
NoMethodError (undefined method `each' for "0":String):
app/helpers/fw_exports_helper.rb:21:in `block in process_spreadsheet'
app/helpers/fw_exports_helper.rb:20:in `process_spreadsheet'
app/controllers/fw_exports_controller.rb:82:in `process_parsed_spreadsheet'
代码中的相同位置,不同的消息。
答案 0 :(得分:1)
在执行
之后添加|i|
for i in 1..number_of_rows do |i|
在评论回复后编辑:
您没有显示模型,但可能有一个名为location
的关系与该字段冲突。
答案 1 :(得分:0)
正如你所说:
class FwExport < ApplicationRecord
has_one :location
并假设:
class Location < ApplicationRecord
belongs_to :fw_export
因此您无法将:location
定义为CreateFwExports
迁移中的字符串列。
首先,您需要编写另一个迁移来从:fw_exports
表中删除列:
class RemoveColumnFromFwExports < ActiveRecord::Migration[5.1]
def change
remove_column :fw_exports, :location, :string
end
end
现在重写帮助方法,该方法将位置字符串从csv解析为Location
实例并将其分配到FwExport
实例中:
def process_spreadsheet(number_of_rows, spreadsheet)
1.upto(number_of_rows) do |i|
fw_export_record = FwExport.new(
screen_name: spreadsheet[i][0].to_s,
full_name: spreadsheet[i][1].to_s,
)
fw_export_record.save
# now create the location and associate it to fw_export_record
location = find_or_create_location(spreadsheet[i][2].to_s)
location.fw_exports_id = fw_export_record.id
location.save
end
end
private
def find_or_create_location(s)
city, country = s.split(',').map(&:strip)
Location.find_or_create_by!(city: city, country: country)
end