2017-07-07 49 views
2

我对rails开发相对较新,希望得到一些指导。在Rails 5中为从CSV导入的所有数据分配一个值

我在那里,我从一个CSV文件导入数据的应用程序。我的目标是为导入的CSV(移动ID)分配一个值,以将所有导入的数据分组。

例如(我目前有工作)。我有一组员工需要迁移到新的位置,我有一个名为Move的表has_many employee_moves(另一个表)。我有一个collection_select,可以从存在的Move_IDs中选择。我还可以导入一个CSV文件,将每行分配给我现有的Employee_Move表。

我想,如果可能的话,要能够选择Move_ID,选择我的CSV文件导入和每个记录从CSV文件到我的选择Move_ID关联。基本上将该员工的CSV分配给特定的移动。

我能够立刻在编辑视图导入的时间使用部分我已经创建了一个手动分配这些值。

<%= render 'form' %> 

我希望这是所有决策意识...

我一直在试图解决这个有一段时间了,所以请原谅(并随时指出)任何冗余的代码,其可从我以前的尝试剩余。

EmployeeMove型号

require 'csv' 

    attr_accessor :move 

    belongs_to :move, optional: true 
    belongs_to :location, optional: true 

    def self.import(file) 
    CSV.foreach(file.path, headers: false) do |row| 
     EmployeeMove.create!({ 
     :person => row[1], 
     :from_building => row[2], 
     :from_floor => row[3], 
     :from_room => row[4], 
     :to_building => row[5], 
     :to_floor => row[6], 
     :to_room => row[7], 
     :notes => row[8], 
     :move_id => move.id <-- I know this is my problem. 
     }) 
    end 
    end 

EmployeeMovesController

class EmployeeMovesController < ApplicationController 

    def index 
    @employee_moves = EmployeeMove.all 
    end 

    def new 
    @employee_move = EmployeeMove.new 
    end 

    def create 
    @employee_move = EmployeeMove.new(employee_move_params) 
    if @employee_move.save 
     flash[:notice] = "Employee Move successfully added" 
     redirect_to employee_move_path(@employee_move) 
    else 
     render 'new' 
    end 
    end 

    def show 
    @employee_move = EmployeeMove.find(params[:id]) 
    end 

    def edit 
    @employee_move = EmployeeMove.find(params[:id]) 
    end 

    def update 
    @employee_move = EmployeeMove.find(params[:id]) 
    if @employee_move.update(employee_move_params) 
     flash[:notice] = "Emplyee Move successfully updated" 
     redirect_to employee_move_path(@employee_move) 
    else 
     render 'edit' 
    end 
    end 

    def import 
    EmployeeMove.import(params[:file]) 
    redirect_to employee_moves_path, notice: "CSV Imported." 
    end 


    private 
    def employee_move_params 
    params.require(:employee_move).permit(:id, :person, :from_building, :from_floor, :from_room, :to_building, :to_floor, :to_room, :comments, :notes, 
              :Complete, :move_id, :location_id) 
    end 

end 

我Collection_Select

目前位于员工移动的新的编辑页面,也使用_form p artial。

<%= form_for @employee_move do |f| %> 

<p> 
    <%= f.label :Move_ID %>&nbsp 
    <%= collection_select(:employee_move, :move_id, Move.all, :id, :id, { :prompt => true }, { :multiple => false}) %> 
</p> 
<p> 
    <%= f.label :employee_move_name %>&nbsp 
    <%= f.text_field :person %> 
</p> 
<p> 
    <%= f.label :From_Building %>&nbsp 
    <%= f.text_field :from_building %> 
</p> 
<p> 
    <%= f.label :From_Floor %>&nbsp 
    <%= f.text_field :from_floor %> 
</p> 
<p> 
    <%= f.label :From_Room %>&nbsp 
    <%= f.text_field :from_room %> 
</p> 
<p> 
    <%= f.label :To_Building %>&nbsp 
    <%= f.text_field :to_building %> 
</p> 
<p> 
    <%= f.label :To_Floor %>&nbsp 
    <%= f.text_field :to_floor %> 
</p> 
<p> 
    <%= f.label :To_Room %>&nbsp 
    <%= f.text_field :to_room %> 
</p> 
<p> 
    <%= f.label :Comment %>&nbsp 
    <%= f.text_field :comments %> 
</p> 
<p> 
    <%= f.label :Note %>&nbsp 
    <%= f.text_field :notes %> 
</p> 
<p> 
    <%= f.submit %> 
</p> 

<% end %> 

一想到写这篇,我宁愿我的CSV导入到位于我移动显示页面(不意味着员工移动显示页)。我目前有一个移动索引页面,可以从创建的移动列表中进行选择。从这个列表中选择一个移动,我可以看到移动的详细信息,后面跟随着该移动的每个员工部分填充的表格。这是目前正在工作,但正如我之前所述,只有当我已经导入CSV文件后手动分配Move_ID给员工。

第一次海报在这里,所以请让我知道如果我可以提高我的问题进行了信息。

感谢制作了这一步,通过我的文字的墙。

============================================== =========

更新

感谢您的帮助迄今简单的石灰。以下是建议的更改。正如我在下面的评论中提到的,我目前获得"undefined method 'import' for # <Move:0x00000004388a20>"。这些是自从我的原始帖子以来所做的更改。

导入方法

我提出我的导入方法从我EmployeeMoveController我MoveController。

def import 
    @move = Move.find(params[:move_id]) 
    @move.import(params[:file]) 
    redirect_to moves_path(@move), notice: "CSV Imported." 
    end 

瑞克路线

import_moves POST /moves/import(.:format)   moves#import 
    move_import GET /moves/:move_id/import(.:format) moves#import 

我手动添加第二路线“move_import”,但由于原(import_moves)也指向同一控制器#动作,也许有某种形式的冲突发生在这里?我不确定。

我的移动显示页面中的以下代码正确地指示我到正确的URL/moves/1/import。

<%= link_to "Add Employees to Move", move_import_path(@move.id) %> 

员工移动模式

我已经删除了:move_id => move.id

class EmployeeMove < ActiveRecord::Base 
    require 'csv' 

    attr_accessor :move 

    belongs_to :move, optional: true 
    belongs_to :location, optional: true 

    def self.import(file) 
    CSV.foreach(file.path, headers: false) do |row| 
     self.employee_moves.create!({ 
     :person => row[1], 
     :from_building => row[2], 
     :from_floor => row[3], 
     :from_room => row[4], 
     :to_building => row[5], 
     :to_floor => row[6], 
     :to_room => row[7], 
     :notes => row[8] 
     }) 
    end 
    end 
end 

导入浏览(HTML)

我import.html.erb文件位于/视图/ employee_moves。

<div class="col-md-6"> 
    <div class="panel panel-default "> 
    <div class="panel-body"> 
     <h1>move</h1> 
     <h1>Move</h1> 
     <p> 
     Move ID: 
     <%= @move.id if @move%> 
     </p> 

     <%= form_tag import_employee_moves_path, multipart: true do %> 
     <%= file_field_tag :file %> 
     <%= submit_tag "Import" %> 
     <% end %> 

     <%= link_to "All Moves", moves_path %> 
    </div> 
    </div> 
</div> 

我希望这个更新能够很好地解释我的问题的当前状态。请让我知道是否需要更多信息。

再次!感谢您对我的学习给予的所有帮助和耐心。

==============================================这得到了==============

最终修改这方面的工作我要我

我感动从我Employee_Move模型我self.import我的移动模式和自删除,使其成为实例方法。

我在routes.rb中改变了get 'import'post 'import'

希望这是帮助这个问题我已经没有任何人。再次感谢Simple Lime提供的所有帮助!

回答

0

因此,假设我正确地理解了所有内容,您有2个型号MoveEmployeeMove。您希望能够从Move显示页面上载CSV并解析该CSV,为CSV中的每一行创建一个EmployeeMove记录,并为您当前所在的页面创建Move

要做到这一点,我会先移动到EmployeeMove.importMove#import(所以,在Move模型的实例方法,而不是在EmployeeMove类方法)。那么,既然你提到Move的has_many employee_moves,而不是EmployeeMove.create!({...}),你可以做

self.employee_moves.create!({...}) 

,而不是需要在创建了该:move_id => move.id线

最后,移动从EmployeeMovesControllerimport方法为MovesController和变化在config/routes.rb的路线看起来更像/moves/:id/import(这里唯一重要的部分是它转到MovesController,并有一个:id移动它的导入到。然后你的导入方法在控制器应该看起来像

def import 
    @move = Move.find(params[:id]) 
    @move.import(params[:file]) # been a while since I've done a file upload, but I assume params[:file] is working here 
    redirect_to moves_path(@move) # or wherever you'd like to send them 
end 

这应该为雅做。如果我误解了你的问题,或者你想进一步澄清某些事情,请告诉我。

+0

所以我不得不离开州工作几个星期,所以我提前为我的回应延误表示歉意。我当前使用的移动URI模式#import是/moves/import(.:format)。我怎样才能改变它传递的id类似于你的建议,/ moves /:id/import。谢谢 – nel

+0

如果你有'resources:moves'你可以'resources:moves do;发布“导入”,在::member;结束',否则你可以只是'后'/移动/:身份证/进口“,以:”移动#导入“' –

+0

我已经成功地添加POST到我的路线使用您与我共享的资源方法。然而,我得到'没有路由匹配[GET]“import/1/import'错误,我发现我的路由中只有一个POST方法,点击我的移动显示页面上的链接' %= link_to“Add Employees to Move”,import_move_path(@move)%>',我也将我的import.html.erb从我的Employee_Move视图文件夹移动到我的移动文件夹。只是给你我所做的更改的完整更新 – nel