Rails使用关联

时间:2016-02-18 16:51:55

标签: ruby-on-rails ruby csv

我正在构建一个将序列号与软件标题相关联的rails应用程序。例如,我有一个软件标题,需要能够上传批量序列号(代码)并将其与该特定软件标题相关联。它需要足够简单,以便用户(经过身份验证)单击上载链接,从下拉列表中选择软件标题并点击导入。这是我到目前为止的...它不一定是一个csv它也可能是一个文本文件。我只是需要帮助找出实现这一目标的最佳方法。

Code Upload UI

代码架构

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

1 个答案:

答案 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]数组中。