我有一个CSV文件,我正在尝试加载到rails数据库。 一切正常,直到它到达名为BW (MB)的列。 我认为这是括号的问题,因为其他标题有空格而且它们很好。 如果可能的话,我想避免重命名原始CSV文件中的标题。
码:
CSV.foreach(csv_file, :headers => true) do |row| Sevonedatum.create!(row.to_hash.slice('Date', 'Market Area', 'BW (MB)')) end错误输出:
ActiveRecord :: MultiparameterAssignmentErrors:分配多参数属性时出错1次[分配错误[“96.26”]到BW(未定义方法`BW ='代表#)]
您可以看到MultiparameterAssignment错误指向将值分配给BW时的问题,但在错误中它缺少(MB)部分。
从迁移文件:
class CreateSevonedata < ActiveRecord::Migration[5.0] def change create_table :sevonedata do |t| t.column :'Date', :date t.column :'Market Area', :string t.column :'BW (MB)', :float t.timestamps end end endI have a CSV file that i'm trying to load to rails database. Everything works fine until it gets to a column named BW (MB). I'm thinking it's an issue with the parentheses as the other headers have spaces and they are fine. I'd like to avoid renaming the header in the original CSV file itself if possible.
Code:
CSV.foreach(csv_file, :headers => true) do |row| Sevonedatum.create!(row.to_hash.slice('Date', 'Market Area', 'BW (MB)')) endError output:
ActiveRecord::MultiparameterAssignmentErrors: 1 error(s) on assignment of multiparameter attributes [error on assignment ["96.26"] to BW (undefined method `BW =' for #)]
You can see the MultiparameterAssignment error is pointing to an issue when the value is being assigned to BW, though in the error it's missing the (MB) portion.
From the migration file:
class CreateSevonedata < ActiveRecord::Migration[5.0] def change create_table :sevonedata do |t| t.column :'Date', :date t.column :'Market Area', :string t.column :'BW (MB)', :float t.timestamps end end end最满意答案
您不能在列名中包含括号:Rails将尝试将列名“BW(MB)”映射到有效的Ruby属性名称,并且不允许使用括号。 空格转换为下划线确定,但不允许使用括号。
看看Active Record如何通过配置实现约定 - 这是Rails的关键原则之一。
Rails允许你做一些覆盖,但你不能有一个“BW(MB)”列等同于一个有效的Ruby类属性。
您有两个选项 - 您需要将列名更改为“BW”。
选项1:编辑CSV文件的标题以使其与列名匹配,并相应地更改代码。
选项2:按标题保留标题,但写入额外的代码以用“BW”替换散列键“BW(MB)”
CSV.foreach(csv_file, :headers => true) do |row| foo = row.to_hash.slice('Date', 'Market Area', 'BW (MB)') foo["BW"] = foo["BW (MB)"] foo.delete("BW (MB)") Sevonedatum.create!(foo) end(你可以把它优化到更少的线 - 我说它是冗长的,因为你说你是初学者)
You can't have parentheses in a column name: Rails will try to map the column name "BW (MB)" to a valid Ruby attribute name, and parentheses aren't allowed. Spaces convert to underlines OK, but parentheses aren't allowed.
Look at how Active Record does convention over configuration - one of the key principles of Rails.
Rails lets you do some amount of overriding, but you can't have a column "BW (MB)" that equates to a valid Ruby class attribute.
You have 2 options - both of which you need to change the column name to "BW".
Option 1: edit the headers of the CSV files so they match the column name, and change your code accordingly.
Option 2: leave the header as-is, but write additional code to replace the hash key "BW (MB)" with "BW"
CSV.foreach(csv_file, :headers => true) do |row| foo = row.to_hash.slice('Date', 'Market Area', 'BW (MB)') foo["BW"] = foo["BW (MB)"] foo.delete("BW (MB)") Sevonedatum.create!(foo) end(you can optimize that to fewer lines - I'm making it verbose since you've said you're a beginner)
更多推荐
发布评论