Reputation: 49
I'm trying to import a .csv to refill and complete many forms, rather than having to fill and create them one by one. I've followed a pretty nifty tutorial here:https://www.youtube.com/watch?v=W8pohTautj8 which has been really helpful. I then tweaked it for nested resources by this post here: https://gorails.com/forum/import-a-csv-with-associations
So far so good. I then made a few final tweaks to get where I was having issues with Authenticity tokens, NilClass errors and now I'm getting wrong number of arguments. All the stack overflow posts that also present this error that I've seen haven't been able to help.
Here's the code:
controller
def create
@development = Development.find(params[:development_id])
@lot = @development.lots.create(params.require[:lot].permit(:status, :lot_number ,:stage, :land_size, :price, :bed, :bath, :car, :rent))
respond_to do |format|
if @lot.save
format.js
format.html { redirect_to Development.find(params[:development_id]), notice: "Lot was successfully created." }
format.json { render :show, status: :created, location: @lot }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @lot.errors, status: :unprocessable_entity }
end
end
end
def import
@development = Development.find(params[:development_id])
@lot = @development.lots.create(params.require[:lot].permit(:status, :lot_number ,:stage, :land_size, :price, :bed, :bath, :car, :rent))
Lot.import(@development, development_params[:lot])
redirect_to development_path, notice: "Lots were successfully created."
end
model
def self.import(development, file)
CSV.foreach(file.path, headers: true) do |row|
development.lots.create! row.to_hash
end
end
_form partial
<%= form_tag import_development_lots_path, multipart: true, remote: true, authenticity_token: true do %>
<%= file_field_tag :file %>
<%= hidden_field_tag :authenticity_token, form_authenticity_token -%>
<%= submit_tag "Upload csv" %>
<% end %>
Note: This is additional to the regular, original form (both on the same _form partial) to create the object. It was my understanding that the original could stay as a means of creating data tables manually, one at a time, as another option to the mass csv import option. Please let me know if I need to add the code for the original form too. They seem to be fine to coexist on the same page together.
routes
resources :lots do
collection { post :import }
end
application.rb
require 'csv'
I believe that's everything related to the csv import; any help is greatly appreciated!
Edit: Here's the error log as requested by Siim.
Started POST "/developments/2/lots" for ::1 at 2021-05-13 10:46:14 +1000
Processing by LotsController#create as HTML
Parameters: {"authenticity_token"=>"s7EpVu4LymhZpm+nSxGF+yLXWY3GqHjwKSN0eccRCws7eTy1riGg9GplIciLIns7hlKYyRipA5tgMbGn0GTGow==", "file"=>"Test Lot.csv", "commit"=>"Upload Stocklist", "development_id"=>"2"}
Development Load (1.3ms) SELECT "developments".* FROM "developments" WHERE "developments"."id" = $1 LIMIT $2 [["id", 2], ["LIMIT", 1]]
↳ app/controllers/lots_controller.rb:71:in `get_development'
CACHE Development Load (0.0ms) SELECT "developments".* FROM "developments" WHERE "developments"."id" = $1 LIMIT $2 [["id", 2], ["LIMIT", 1]]
↳ app/controllers/lots_controller.rb:25:in `create'
Completed 500 Internal Server Error in 14ms (ActiveRecord: 1.3ms | Allocations: 1798)
ArgumentError (wrong number of arguments (given 0, expected 1)):
app/controllers/lots_controller.rb:26:in `create'
Upvotes: 0
Views: 1504
Reputation: 4348
According to your error backtrace (from comments), the error is on the following line:
@lot = @development.lots.create(params.require[:lot].permit(:status, :lot_number ,:stage, :land_size, :price, :bed, :bath, :car, :rent))
If you would break that apart to multiple lines you would get an even more accurate error message to find it out yourself, but I can already see it.
require
is a method that requires an argument. You are calling it without arguments and then accessing it as an array/hash by calling []
on it.
Use params.require(:lot)
instead of params.require[:lot]
.
Upvotes: 1