Reputation: 14272
I have been referring RailsCasts #396 for importing data from csv, xls, xlas files. According to the railscast (Rails 3.2.9) the import method is
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 Csv.new(file.path, nil, :ignore)
when ".xls" then Excel.new(file.path, nil, :ignore)
when ".xlsx" then Excelx.new(file.path, nil, :ignore)
else raise "Unknown file type: #{file.original_filename}"
end
end
but since Rails 4x implements strong params I was getting undefined local variable or method 'accessible_attributes'
error
So I looked up and found this stackoverflow question Rails 4 how to call accessible_attributes from Model, according to the answer I tried
def attr_names
[user_id, last_name, first_name, last_name_kana, first_name_kana, created_at,created_by, updated_at, updated_by, del_flag]
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]
user = find_by(user_id: row["user_id"]) || new
user.attributes = row.to_hash.slice(*attr_names)
user.save!
end
end
def self.open_spreadsheet(file)
case File.extname(file.original_filename)
when ".csv" then Roo::CSV.new(file.path, csv_options: {encoding: "SJIS"})
when ".xls" then Roo::Excel.new(file.path, nil, :ignore)
when ".xlsx" then Roo::Excelx.new(file.path, nil, :ignore)
else raise "Unknown file type: #{file.original_filename}"
end
end
Still getting same error, only this time it is undefined local variable or method 'attr_names'
. Thanks in advance
Upvotes: 1
Views: 1214
Reputation: 1357
Being on the model, you should make it self.attr_names
. Alternatively, all your methods there being self, you could extend self, like so:
extend self
def attr_names
[user_id, last_name, first_name, last_name_kana, first_name_kana, created_at,created_by, updated_at, updated_by, del_flag]
end
def import(file)
spreadsheet = open_spreadsheet(file)
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
user = find_by(user_id: row["user_id"]) || new
user.attributes = row.to_hash.slice(*attr_names)
user.save!
end
end
def open_spreadsheet(file)
case File.extname(file.original_filename)
when ".csv" then Roo::CSV.new(file.path, csv_options: {encoding: "SJIS"})
when ".xls" then Roo::Excel.new(file.path, nil, :ignore)
when ".xlsx" then Roo::Excelx.new(file.path, nil, :ignore)
else raise "Unknown file type: #{file.original_filename}"
end
end
Upvotes: 1