我有一个功能性的ruby应用程序,我是通过跟踪基础架构教程创建的,很少或没有fus,我尝试按照tutorial将多个记录上传到数据库中。 它似乎非常直接,并认为我可以在几分钟内完成它。
问题是当我上传csv文件时,我收到上传成功的通知,首先,只创建一条记录,其次创建的记录为空。
我已经搜索和搜索过,尝试过其他教程并最终遇到同样的问题......我基本上都是在智慧结束。请参阅下面的代码片段:
hospital.rb
class Hospital < ApplicationRecord
mount_uploader :image, ImageUploader
searchkick
has_many :reviews
#validates :name, :address, :phone, :image, presence: true
#validates :website, format: { with: /\Ahttps?:\/\/.*\z/,
#message: "must start with http:// or https://" }
#validates :phone, numericality: {
#only_integer: true,
#message: "must be land line(7 digits) or Gsm(11 digits)"
#}
end
hospital_controller.rb
class HospitalsController < ApplicationController
...
def import
Hospital.import(params[:file])
end
...
def create
@hospital = Hospital.new(hospital_params)
respond_to do |format|
if @hospital.save
format.html { redirect_to @hospital, notice: 'Hospital was successfully created.' }
format.json { render :show, status: :created, location: @hospital }
else
format.html { render :new }
format.json { render json: @hospital.errors, status: :unprocessable_entity }
end
end
end
private
def hospital_params
params.require(:hospital).permit(:name, :address, :city_town, :state, :phone, :website, :safe_care, :jci, :cohsasa, :best_known_4, :image )
end
end
Rails服务器上的输出
Started POST "/hospitals" for ::1 at 2017-06-22 12:58:09 +0100
Processing by HospitalsController#create as HTML
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxx==",
"hospital"=>{"name"=>"",
"address"=>"", "city_town"=>"", "state"=>"", "phone"=>"", "website"=>"",
"safe_care"=>"", "jci"=>"", "cohsasa"=>"", "best_known_4"=>""}, "file"=>#
<ActionDispatch::Http::UploadedFile:0x007fe064b78918 @tempfile=#
<Tempfile:/var/folders/xh/hv6bwdzs3cx4ws9x42n3gsn00000gn/
T/RackMultipart20170622-80750-147ctbc.csv>, @original_filename="Test.csv",
@content_type="text/csv", @headers="Content-Disposition: form-data;
name=\"file\"; filename=\"Test.csv\"\r\nContent-Type: text/csv\r\n">,
"commit"=>"Import CSV"}
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ?
ORDER BY "users"."id" ASC LIMIT ? [["id", 1], ["LIMIT", 1]]
Can't verify CSRF token authenticity.
(0.1ms) begin transaction
(0.1ms) commit transaction
(0.1ms) begin transaction
SQL (0.5ms) INSERT INTO "hospitals" ("name", "address", "phone", "website",
"created_at", "updated_at", "city_town", "state", "jci", "cohsasa",
"best_known_4", "safe_care") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
[["name", ""], ["address", ""], ["phone", ""], ["website", ""], ["created_at",
2017-06-22 11:58:09 UTC], ["updated_at", 2017-06-22 11:58:09 UTC],
["city_town", ""], ["state", ""], ["jci", ""], ["cohsasa", ""],
["best_known_4", ""], ["safe_care", ""]]
(0.8ms) commit transaction
Hospital Store (170.8ms) {"id":53}
Redirected to http://localhost:3000/hospitals/53
Completed 302 Found in 188ms (Searchkick: 170.8ms | ActiveRecord: 1.9ms)
答案 0 :(得分:0)
在模型中尝试下面的代码来导入csv ini db并在控制器中调用它:
def self.import(file)
spreadsheet = open_spreadsheet(file)
header = spreadsheet.row(2)
(3..spreadsheet.last_row).each do |i|
row = spreadsheet.row(i) #Hash[[header, spreadsheet.row(i)].transpose]
f1= from = row[0]
f2 = row[1]
f3 = row[2]
ModelName.create({f1: f1, ... })
end
end
答案 1 :(得分:0)
您的代码的行为完全按照您的行为编写:
首先,只创建一条记录 ...
是的。因为你从不打电话:
Hospital.import(params[:file])
这是在import
行动中,但您从未通过create
行动拨打电话。当教程说:
步骤:3
在控制器中添加块
这并不意味着“你喜欢任何旧地方,它会被神奇地称为”。你必须实际调用逻辑。但是,你没有。所以你的应用程序对CSV文件没有任何作用。这正是您告诉它与CSV文件有关的内容。
(另外,你的Hospital
类没有导入类方法。所以,当你最终调用它时,它会抛出一个错误。)
其次,创建的记录为空...
再次。正如你写的那样。
正如您在控制台中看到的那样,您的医院参数是空的:
Started POST "/hospitals" for ::1 at 2017-06-22 12:58:09 +0100
Processing by HospitalsController#create as HTML
Parameters: {
"utf8"=>"✓",
"authenticity_token"=>"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxx==",
"hospital"=>{
"name"=>"",
"address"=>"",
"city_town"=>"",
"state"=>"",
"phone"=>"",
"website"=>"",
"safe_care"=>"",
"jci"=>"",
"cohsasa"=>"",
"best_known_4"=>""
},
"file"=>#<ActionDispatch::Http::UploadedFile:0x007fe064b78918 @tempfile=#
所以,当你这样做时:
@hospital = Hospital.new(hospital_params)
然后:
if @hospital.save
...
else
...
end
嗯,你刚刚告诉你的应用程序创建了一个空白记录,并且它很快就符合要求(特别是因为你已经删除了所有的验证)。
所以...编写Hospital.import方法(参见教程的第4步),如下所示:
class Hospital < ApplicationRecord
mount_uploader :image, ImageUploader
searchkick
has_many :reviews
#validates :name, :address, :phone, :image, presence: true
#validates :website, format: { with: /\Ahttps?:\/\/.*\z/,
#message: "must start with http:// or https://" }
#validates :phone, numericality: {
#only_integer: true,
#message: "must be land line(7 digits) or Gsm(11 digits)"
#}
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
Hospital.create! row.to_hash
end
end
end
在您的控制器中调用它,例如:
def create
import if params[:file] # <= this here is the call to your import method
@hospital = Hospital.new(hospital_params)
respond_to do |format|
if @hospital.save
format.html { redirect_to @hospital, notice: 'Hospital was successfully created.' }
format.json { render :show, status: :created, location: @hospital }
else
format.html { render :new }
format.json { render json: @hospital.errors, status: :unprocessable_entity }
end
end
end
重新添加您的验证。您将在途中更接近。