Rails 4如何从Model调用accessible_attributes

嗨,我在Rails演员( 导入csv Excel文件 )上尝试这个tuto。 我在这行product.attributes = row.to_hash.slice(*accessible_attributes)上有错误

对于#`, undefined local variable or method accessible_attributes’

这是我的模特。

 class Product < ActiveRecord::Base require 'roo' validates_presence_of :price #attr_accessible :name, :price, :released_on #I removed this line (rails 4) def self.to_csv(options = {}) CSV.generate(options) do |csv| csv << column_names all.each do |product| csv << product.attributes.values_at(*column_names) end end end def self.import(file) spreadsheet = open_spreadsheet(file) header = spreadsheet.row(1) (2..spreadsheet.last_row).each do |i| row = Hash[[header, spreadsheet.row(i)].transpose] product = find_by_id(row["id"]) || new product.attributes = row.to_hash.slice(*accessible_attributes) product.save! end end def self.open_spreadsheet(file) case File.extname(file.original_filename) when ".csv" then Roo::Csv.new(file.path) when ".xls" then Roo::Csv.new(file.path) when ".xlsx" then Roo::Csv.new(file.path) else raise "Unknown file type: #{file.original_filename}" end end end 

在我的控制器上结束我定义了product_params

 def product_params params.require(:product).permit(:name, :price, :released_on) end 

我想要导入的我的csv看起来像这样:

 id,name,realased_on,price,created_at,updated_at 1,Acoustic Guitar,2012-10-03,3456.54,2013-12-09 00:00:23 UTC, 2012-12-08 23:45:46 UTC 

实际上accessible_attributes获取那些在模型中声明为attr_accessible列,但是在rails 4中他们已经从模型中删除了attr_accessible并使用了strong_parameter而不是这样,因此在他的模型中创建一个同名方法accessible_attributes然后在该方法内部声明该列数组你想要哪个。 如:

 def accessible_attributes [col1_name, col2_name, ....] end 

在Rails 4.1下处理这个Railscast时,我通过用row.to_hash.keys替换accessible_attributes来获得工作方法。

 def self.import(file) spreadsheet = open_spreadsheet(file) header = spreadsheet.row(1) (2..spreadsheet.last_row).each do |i| row = Hash[[header, spreadsheet.row(i)].transpose] product = find_by_id(row["id"]) || new product.attributes = row.to_hash.slice(*row.to_hash.keys) product.save! end end 

使用已接受的解决方案对我来说并不奏效。 我需要添加“自我”。 方法定义使其工作。

另一种方法是,如果您调用accessible_attributes的唯一位置是self.import,则将您要查找的字段定义为本地数组变量。

 def self.import(file) accessible_attributes = ['my_attribute_name1','my_attribute_name2', '...'] spreadsheet = open_spreadsheet(file) header = spreadsheet.row(1) (2..spreadsheet.last_row).each do |i| row = Hash[[header, spreadsheet.row(i)].transpose] cae = find_by_id(row["id"]) || new cae.attributes = row.to_hash.slice(*accessible_attributes) cae.save! end end 

回答上一个问题,为什么validation消息显示“价格不能为空”。 我认为这可能是由于数据在Excel中保存为通用格式。 我遇到了类似的问题,在将其更改为文本格式后,错误消息消失了。 我不知道原因,但试一试。