我正在构建一个将序列号与软件标题相关联的rails应用程序。例如,我有一个软件标题,需要能够上传批量序列号(代码)并将其与该特定软件标题相关联。它需要足够简单,以便用户(经过身份验证)单击上载链接,从下拉列表中选择软件标题并点击导入。这是我到目前为止的...它不一定是一个csv它也可能是一个文本文件。我只是需要帮助找出实现这一目标的最佳方法。
代码架构
create_table "codes", force: :cascade do |t|
t.integer "software_id"
t.integer "user_id"
t.string "label"
t.string "code"
t.string "in_use"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "codes", ["software_id"], name: "index_codes_on_software_id"
add_index "codes", ["user_id"], name: "index_codes_on_user_id"
代码'表格'用于UI
<%= simple_form_for(@code) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.association :software %>
<%= f.input :label %>
<%= f.input :code %>
</div>
<div class="form-actions">
<%= f.file_field :code %>
<br>
<%= f.button :submit, "Upload Codes", class: 'btn btn-warning' %>
</div>
<br>
<% end %>
Code.rb模型
class Code < ActiveRecord::Base
belongs_to :software
belongs_to :user
accepts_nested_attributes_for :software
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
Code.create! row.to_hash
end
end
end
Software.rb模型
class Software < ActiveRecord::Base
has_many :software_assigns
has_many :products, through: :software_assigns
has_many :software_downloads
has_many :codes
end
代码控制器
class CodesController < ApplicationController
before_action :authenticate_user!
before_action :verify_admin
before_action :set_code, only: [:show, :edit, :update, :destroy]
# GET /codes
# GET /codes.json
def index
@codes = Code.all
end
# GET /codes/1
# GET /codes/1.json
def show
end
# GET /codes/new
def new
@code = Code.new
end
# GET /codes/1/edit
def edit
end
# POST /codes
# POST /codes.json
def create
@code = Code.new(code_params)
respond_to do |format|
if @code.save
format.html { redirect_to @code, notice: 'Codes were successfully created.' }
else
format.html { render :new }
end
end
end
# PATCH/PUT /codes/1
# PATCH/PUT /codes/1.json
def update
respond_to do |format|
if @code.update(code_params)
format.html { redirect_to @code, notice: 'Codes were successfully updated.' }
else
format.html { render :edit }
end
end
end
# DELETE /codes/1
# DELETE /codes/1.json
def destroy
@code.destroy
respond_to do |format|
format.html { redirect_to codes_url, notice: 'Codes were successfully destroyed.' }
end
end
def import
Code.import(params[:file])
redirect_to codes_path, notice: 'Codes were successfully uploaded!'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_code
@code = Code.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def code_params
params.require(:code).permit(:software_id, :label, :code)
end
end
答案 0 :(得分:0)
好的 - 在评论中做了很多沟通,我想我现在可以把答案放在一起了。
所以,根据我对pitabas prathal的回答的编辑,你需要通过code_params哈希中的:code
键来查找,但是因为Code类不知道你有{{1}要参考,你需要传递它。所以你的导入方法就变成了:
<强> code.rb 强>
code_params[:software_id]
然后,使用新参数调用此方法,来自def self.import(file, software_id)
CSV.foreach(file.path, headers: true) do |row|
code = Code.new row.to_hash
code.software_id = software_id
code.save!
end
end
操作(或控制器上的create
方法):
import
现在,您将为您的Code类提供将新Code.import(code_params[:code], code_params[:software_id])
对象与相应的Code
对象相关联所需的所有信息。
修改强>
在你的GoRails帖子中,Chris Oliver的答案也可以,只需一个编辑:
Software
不起作用 - @software = Software.find(params[:software_id])
为零。您可以从params[:software_id]
哈希:
software_id
code_params
或者将[:code]键添加到params参考中,如下所示:
@software = Software.find(code_params[:software_id])
因为[:software_id]位于@software = Software.find(params[:code][:software_id])
哈希的[:code]数组中。