【问题标题】:Parsing and saving an array of items submitted by POST as separate, individual items将 POST 提交的一系列项目解析并保存为单独的单独项目
【发布时间】:2014-07-14 17:33:56
【问题描述】:

我的用户正在提交包含多个项目的请求。无论项目如何保存到 SQL 数据库中,为了便于分析,我都需要解析每个项目并将其作为单独的数据行保存在 Excel 文件(Google Drive)中。

换句话说,在 SQL 中,请求看起来像这样:{:name => "john", :email => "john@gmail.com", :items => ["a", "b", "c"],但我需要将其转换为每个项目有 3 行的文档,并且各行之间唯一不同的是项目。

  • 第 1 行的名称 = John,电子邮件 = John@gmail.com,项目 = a
  • 第 2 行的名称 = John,电子邮件 = John@gmail.com,项目 = b
  • 第 3 行的名称 = John,电子邮件 = John@gmail.com,项目 = c

我在下面的工作,但我想知道它是否是最有效的,无论是从以下角度来看:

  1. 有没有更简单的方法来获取参数?
  2. 是否有更简单的方法来解析和保存单个数据?

谢谢!

型号代码

class Request < ActiveRecord::Base

  serialize :items
  validate :must_have_one_item

  def must_have_one_item
    errors.add(:items, 'You must select at least one item') unless self.items.detect { |i| i != "0" } 
  end

end

查看代码

<%= f.check_box(:items, {:multiple => true}, "#{thing}") %>
<%= f.label(:items, "#{thing}") %>

这里,thing 是迭代器函数的一部分,它遍历要选择的潜在项目的预定义列表。

CONTROLLER 代码,包含大量 cmets!

class RequestsController < ApplicationController

  def new
    @requestrecord = Request.new
  end

  def create
    @requestrecord = Request.new(request_params) 

    if @requestrecord.save

      # Given model/ form code so far, the items are passed through as an array. The remaining comments uses the example: @requestrecord.items = ["water filter", "tent", "0", "0", "0"]. What happens is that "0" represents blank checkboxes
      @requestrecord.items.select! { |x| x != "0" } #removes blank checkboxes; @requestrecord.items = ["water filter", "tent"]
      num_of_requests = @requestrecord.items.count #counts number of items requested; num_of_requests = 2

      i = 0 
      cloned_request = Hash.new
      while i < num_of_requests do
         cloned_request[i] = Marshal.load(Marshal.dump(@requestrecord)) #creates a cloned_request[0] = @requestrecord and cloned_request[1] = @requestrecord 
         cloned_request[i].items = @requestrecord.items.slice(i) #disaggregates the items into the cloned_requests; cloned_request[0].items = "water filter",  cloned_request[1].items = "tent" 
         i += 1
      end

      cloned_request.each do | key, request |
          request.save_spreadsheet
      end

    else
      render 'new'
    end
  end

  private
    def request_params
      params.require(:request).permit({:items => []})
    end

end

【问题讨论】:

    标签: ruby-on-rails ruby forms


    【解决方案1】:

    同意Enraged Camel - 我认为你可以让你的create 方法更加高效:

    #app/controllers/requests_controller.rb
    Class RequestsController < ApplicationController
        def create
            items = params[:request][:items]
            if items.kind_of?(Array)
                #means there are multiple array items
                for item in items do
                   request = Request.new(your: item[:attribute], and: item[:another_attribute])
                   request.save
                end
            else
                request = Request.new(request_params)
                request.save
            end
        end
        private
    
        def request_params
           request.require(request).permit(:your, :attributes)
        end
    end
    

    没有偷窃的意思 任何人的雷声;只是希望您从我发布的内容中获得更多想法!

    【讨论】:

    • 谢谢!请问your是什么?
    • 抱歉,这意味着您的每个请求的属性(如果您要保存单个记录)
    【解决方案2】:

    好的,这里有很多问题。

    首先,尽量不要在数据库中存储数据数组,就像您对serialize :items 所做的那样。你可以阅读更多关于为什么here。你应该做的是有一个名为Item 的模型,它有自己的表。从那里,您可以使用更多模型将其与其他模型相关联,例如具有 item_id 和 user_id 属性为整数的UserItem 模型。此 UserItems 是您的关联模型,它包含有关项目和用户如何关联的信息(即哪些用户拥有哪些项目)。如果需要关联请求和项目,您也可以创建一个 RequestItem 模型。

    当用户提交项目列表时,您可以从 params[:request][:items] 哈希中获取每个项目并使用

    params[:request][:items].each do |item|
      UserItem.create(user_id: @user.id, item_id: item.to_i)
    end
    

    注意上面写着item.to_i。这是因为,一旦你有了 Items 表,每个项目都会有一个 id。一旦您更改视图以向您发送 item_id(而不是项目名称),您可以使用上述逻辑轻松为其创建 UserItems。 (使用 to_i 是因为大多数时候数据以字符串形式发送,您需要将其转换为整数)。

    其次,您确实应该将业务逻辑移至适当的模型,或者至少是一个助手。作为一个原则,你的控制器应该是“瘦的”,你的模型应该是“胖的”。这有很多原因,但在我看来,最重要的原因是它使您的代码更容易测试。你可以阅读更多关于这个here的信息。

    【讨论】:

    • 您好,感谢您的发帖!关于第二点,是的,我完全同意……我打算稍后把它搬出去,谢谢你的抓住。首先,非常感谢您让我知道!你说的绝对有道理,我会进一步考虑。我也在考虑什么时候需要这些数据以及是否要添加另一个表(已经有几个)来跟踪。
    • 您可以拥有的桌子数量确实没有限制。表只是一个组织信息的地方。只要您不跨表重复信息(例如,用于类似目的的两个表),请随时根据需要创建它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-19
    相关资源
    最近更新 更多