I have a view at the route 'memorisation'
and it has an file import for CSV file-types. When I run the import, all of the changes seem to be working fine for all 139 records. However, I am still getting an error.
NoMethodError in MemorisationController#import
undefined method `[]' for nil:NilClass
This is my controller method:
def import
require 'csv'
all_targets = MemoTarget.order(:id).includes(:memo_level).map do |t|
{
:id => t.id,
:target => t.target_number,
:level => t.memo_level.level_number
}
end
CSV.foreach(params[:file].path, headers: true) do |row|
the_target = MemoTest.create do |test|
test.student_id = row["student_id"]
test.teacher_id = session[:user_id]
test.memo_target_id = all_targets.find {|t| t[:level] == row["memo_level"].to_i and t[:target] == row["memo_target"].to_i}[:id]
test.result = true
end
end
redirect_to '/memorisation', notice: 'Student memorisation current targets imported'
end
The line test.memo_target_id = all_targets.find {|t| t[:level] == row["memo_level"].to_i and t[:target] == row["memo_target"].to_i}[:id]
is throwing the error.
In my server log, all the expected changes are being made as shown by the SQL COMMITs
. After the commits, the controller should redirect back to the memorisation
page.
...
(0.7ms) COMMIT
(0.3ms) BEGIN
SQL (0.5ms) INSERT INTO "memo_tests" ("student_id", "teacher_id", "memo_target_id", "result", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["student_id", 139], ["teacher_id", 1], ["memo_target_id", 30], ["result", "t"], ["created_at", "2015-09-13 08:08:05.205922"], ["updated_at", "2015-09-13 08:08:05.205922"]]
(0.6ms) COMMIT
Completed 500 Internal Server Error in 6145ms
NoMethodError (undefined method `[]' for nil:NilClass):
app/controllers/memorisation_controller.rb:33:in `block (2 levels) in import'
app/controllers/memorisation_controller.rb:30:in `block in import'
app/controllers/memorisation_controller.rb:29:in `import'
Rendered /Users/Javu/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_source.erb (135.6ms)
Rendered /Users/Javu/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (69.8ms)
Rendered /Users/Javu/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (13.1ms)
Rendered /Users/Javu/.rbenv/versions/2.2.0/lib/ruby/gems/2.2.0/gems/actionpack-4.2.0/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (270.0ms)
Cannot render console with content type multipart/form-dataAllowed content types: [#<Mime::Type:0x007fd4d2cd4c28 @synonyms=["application/xhtml+xml"], @symbol=:html, @string="text/html">, #<Mime::Type:0x007fd4d2cd4868 @synonyms=[], @symbol=:text, @string="text/plain">, #<Mime::Type:0x007fd4d2ccc2a8 @synonyms=[], @symbol=:url_encoded_form, @string="application/x-www-form-urlencoded">]
I've looked through it with byebug
to see if there was any problem with the import or the 139th record, but everything seems to be fine.
I want to know what's causing this errot and how to rectify it.
row
is nil
in your CSV file that is why you are getting this error, try below code it will work.
def import
require 'csv'
all_targets = MemoTarget.order(:id).includes(:memo_level).map do |t|
{
:id => t.id,
:target => t.target_number,
:level => t.memo_level.level_number
}
end
CSV.foreach(params[:file].path, headers: true) do |row|
next if row.all?(&:blank?)
the_target = MemoTest.create do |test|
test.student_id = row["student_id"]
test.teacher_id = session[:user_id]
test.memo_target_id = all_targets.find {|t| t[:level] == row["memo_level"].to_i and t[:target] == row["memo_target"].to_i}[:id]
test.result = true
end
end
redirect_to '/memorisation', notice: 'Student memorisation current targets imported'
end