在 Rails 中将 2 个表导出为 CSV [如何选择特定列?]

Posted

技术标签:

【中文标题】在 Rails 中将 2 个表导出为 CSV [如何选择特定列?]【英文标题】:Exporting 2 tables to CSV in Rails [how to select specific columns?] 【发布时间】:2021-03-04 08:46:36 【问题描述】:

我一直在尝试在 Rails 中将数据库导出为 CSV。经过多次尝试和错误,我终于让它工作了,现在我的 CSV 包含完整的 2 个表。

但是,我似乎无法从每个表中仅提取某些列 - 小时日志名称、小时日志描述、小时日志小时、小时日志 created_at 和项目名称(在所附照片中标记为红色)。

我在网上找到的所有解决方案都是提取整个表格。

这是我的模型(用于小时日志):

class Hourlog < ApplicationRecord

    belongs_to :user
    belongs_to :project
    accepts_nested_attributes_for :project
    validates :name, presence: true
    validates :description, presence: true
    validates :hours, presence: true
    validates :date, presence: true
    validates :project, presence: true

      def self.to_csv
        CSV.generate do |csv|
          csv << column_names
          all.each do |hourlog|
            csv << (hourlog.attributes.values_at(*column_names) + hourlog.project.attributes.values )
          end
        end
      end
end

这是我的控制器(用于小时日志):

def index 
    @user = User.all
    @filter = Filter.first
    @project = Project.all
    [... a bunch of code that defines @hourlogs...] 

    respond_to do |format|
      format.html
      format.csv  render text: @hourlogs.to_csv 
    end
end 

这是视图:

<%= link_to "CSV", hourlogs_path(format: "csv") %>

这是小时日志的架构:

create_table "hourlogs", force: :cascade do |t|
    t.string   "name"
    t.string   "project"
    t.text     "description"
    t.integer  "hours"
    t.datetime "created_at",     null: false
    t.datetime "updated_at",     null: false
    t.integer  "user_id"
    t.datetime "date"
    t.integer  "project_id"
    t.datetime "date_from"
    t.datetime "date_to"
    t.string   "project_filter"
    t.index ["project_id"], name: "index_hourlogs_on_project_id", using: :btree
    t.index ["user_id"], name: "index_hourlogs_on_user_id", using: :btree
  end

这是项目的架构:

create_table "projects", force: :cascade do |t|
    t.string   "name"
    t.text     "description"
    t.string   "plan"
    t.integer  "planhours"
    t.integer  "thours"
    t.datetime "created_at",                    null: false
    t.datetime "updated_at",                    null: false
    t.datetime "plandate"
    t.datetime "starthourtrack"
    t.integer  "duration"
    t.text     "notes"
    t.boolean  "status",         default: true
  end

任何帮助将不胜感激,我已经挣扎了 10 个小时,似乎无法得到它。 我尝试创建一个单独的 index.csv.erb 文件,概述标题名称,选择 hourlog.name,而不是 hourlog.attributes.values_at(*column_names),但我似乎无法获得正确的语法/逻辑。 谢谢!

[编辑:解决方案] 看起来我只需要一些括号 - 我添加了特定的列名来限制显示的列数,然后我写出了我需要的每一列(hourlog.name、hourlog.description 等) - 我没有意识到我需要将它们放在 [] 中,在 "csv

def self.to_csv
        CSV.generate do |csv|
          column_names = %w(Project Name Description Hours Date)
          csv << column_names
          all.each do |hourlog|
            csv << [hourlog.project.name, hourlog.name, hourlog.description, hourlog.hours, hourlog.created_at]
          end
        end
      end

【问题讨论】:

【参考方案1】:

看起来我只需要一些括号 - 我添加了特定的列名来限制显示的列数,然后我写出了我需要的每一列(hourlog.name、hourlog.description 等)——我没有意识到我需要把它们放在 [] 中,在 "csv

def self.to_csv
        CSV.generate do |csv|
          column_names = %w(Project Name Description Hours Date)
          csv << column_names
          all.each do |hourlog|
            csv << [hourlog.project.name, hourlog.name, hourlog.description, hourlog.hours, hourlog.created_at]
          end
        end
end

【讨论】:

以上是关于在 Rails 中将 2 个表导出为 CSV [如何选择特定列?]的主要内容,如果未能解决你的问题,请参考以下文章

如何在导出时隐藏Rails Admin CSV选项

在C#中将CSV文件导出到DataGridview

如何:在 MySQL 工作台中将记录集导出为分号分隔的 csv 文件?

如何在 Angular 中将动态 JSON 对象数组导出为 CSV?

在 google chrome 浏览器中将 HTML 表导出为 csv

在 R 中将 UTF-8 BOM 导出为 .csv