【问题标题】:Rails 5 CSV merge exportRails 5 CSV 合并导出
【发布时间】:2018-09-11 22:27:51
【问题描述】:

我正在尝试从我的 rails 应用程序的表中导出 CSV 文件。我可以导出 booking.attributes.values 并且可以单独导出 booking.user.attributes.values 但是当我尝试合并这两个时我收到一个错误。

“没有将Array隐式转换为Hash”

这是我正在使用的代码,包括一些注释代码。 csv 文件只提取了 booking.attributes 的标题。这是我需要弄清楚的额外内容。

预订模式

    def self.to_csv(options = {})
#       desired_columns = ["fname","lname","email","nationality","date_of_birth","phone_number"]
        CSV.generate(options) do |csv|
            csv << column_names
            all.each do |booking|
#               csv << booking.user.attributes.merge(booking.course.attributes).values_at(*desired_columns)
#               csv << booking.user.attributes.values
#               csv << booking.attributes.values
                csv << booking.attributes.merge(booking.user.attributes.values).values
            end
        end
end

预订控制器

   def index
        @bookings = Booking.all.paginate(page: params[:page], per_page: 20)

        # respond to look for html but also csv data and xls
        respond_to do |format|
        format.html
        format.csv { send_data @bookings.to_csv }
        format.xls 
        end
    end

这是我尝试以 CSV 格式重新创建的表格视图。这按预期工作。

    <table class="table">
  <thead class="thead-dark">
    <tr>
      <th scope="col">Name</th>
      <th scope="col">Email</th>
      <th scope="col">Nationality</th>
      <th scope="col">D.O.B</th>
      <th scope="col">Phone Number</th>
      <th scope="col">Course Name</th>
      <th scope="col">Course Start</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody id="bookingTable">
    <% @bookings.each do | booking | %>
      <tr>
       <td scope="row"><%= booking.user.fname %> <%= booking.user.lname %></td>
        <td scope="row"><%= booking.user.email %></td>
        <td scope="row"><%= booking.user.nationality %></td>
        <td scope="row"><%= booking.user.date_of_birth&.strftime("%d/%m/%Y") %></td>
        <td scope="row"><%= booking.user.phone_number %></td>
        <td scope="row"><%= booking.course.title %></td>
        <td scope="row"><%= booking.schedule.start_date&.strftime("%d %B %Y") %></td>
        <td><%= link_to 'View User', user_path(booking.user), class: "btn btn-info" %></td>
      </tr>
    <% end %>
  </tbody>
</table>

任何方向都将不胜感激。谢谢。

【问题讨论】:

    标签: ruby csv ruby-on-rails-5


    【解决方案1】:

    CSV 需要一个数组作为一行,而你却在搞乱哈希:

    #      ⇓      hash      ⇓       ⇓         hash        ⇓ array ⇓ array ⇓
    csv << booking.attributes.merge(booking.user.attributes.values).values 
    

    合并哈希是危险的,因为如果userbooking 具有相同的键,则后者将被丢弃。您想要的可能只是将两个值数组相加:

    csv << (booking.attributes.values + booking.user.attributes.values)
    

    或者,如果用户的字段要先行:

    csv << (booking.user.attributes.values + booking.attributes.values)
    

    【讨论】:

    • 感谢一百万个 mudasobwa,您的解释帮助我理解了这里发生的事情,但丹首先解决了我遇到的问题。我认为你们俩都是对的。不确定谁应该获得标记的程序。
    • @Bradley 再次:如果bookinguser 有属性键冲突(例如,两者都有一个名为“name”的属性)合并 hashes 预先将丢弃前一个属性。添加数组将保存这两个属性。
    • 所以通过将它们制作成数组并将它们加在一起,就像这样 csv
    • 当然可以。尝试在控制台中使用简单的哈希值生成csv,例如:{foo: :bar}{foo: 42}
    • 不知道,所以我已经完成了 csv_string = {foo: :bar}, {foo: 42} 并得到了 "{:foo=>:bar},{:foo=>42 的结果}\n" 输入时:csv_string.to_csv 我想这证明了你的观点,它在两者上都吐出了 :foo 但我仍然无法在我的应用程序中获取 csv 文件来打印更多的标题,而不仅仅是预订标题而不是实际预订。 schedule 或 booking.user 标题。抱歉,这只是让我感到困惑。
    【解决方案2】:

    我认为您的问题是您将预订的属性(哈希)与预订的用户属性值(数组)不匹配

    因此,正如错误消息所示,计算机无法知道哪些值属于哪些键。

    我猜你打算写:

    booking.attributes.merge(booking.user.attributes).values

    确实写过:

    booking.attributes.merge(booking.user.attributes.values).values

    无论如何,你要合并的东西都需要密钥!

    【讨论】:

    • 感谢一百万丹。这确实成功了,感谢您的解释。上面 mudasobwa 的回答也会引导我走上正确的道路,但是因为您是第一个进入并且它解决了我的问题,所以我将其添加为答案。关于如何拉入所有列的任何想法。现在我只得到了预订标头,但也想添加 booking.user 标头。谢谢。
    猜你喜欢
    • 2018-08-31
    • 2017-03-18
    • 2020-09-05
    • 2010-12-06
    • 1970-01-01
    • 2021-11-17
    • 2021-03-03
    • 1970-01-01
    • 2017-03-12
    相关资源
    最近更新 更多