Hen*_*hiu 44 ruby csv ruby-on-rails
我得到了一系列我希望转换为CSV的ActiveRecord模型.我尝试过研究像FasterCSV这样的宝石,但它们似乎只使用字符串和数组,而不是ActiveRecord模型.
简而言之,我想转换:
user1 = User.first
user2 = User.last
a = [user1, user2]
Run Code Online (Sandbox Code Playgroud)
至:
id,username,bio,email
1,user1,user 1 bio,user1 email
1,user2,user 2 bio,user2 email
Run Code Online (Sandbox Code Playgroud)
有一个简单的Rails方法来做到这一点?
rud*_*ph9 102
以下内容将所有用户的属性写入文件:
CSV.open("path/to/file.csv", "wb") do |csv|
csv << User.attribute_names
User.find_each do |user|
csv << user.attributes.values
end
end
Run Code Online (Sandbox Code Playgroud)
同样,您可以创建CSV字符串:
csv_string = CSV.generate do |csv|
csv << User.attribute_names
User.find_each do |user|
csv << user.attributes.values
end
end
Run Code Online (Sandbox Code Playgroud)
Bri*_*ian 11
@ rudolph9的答案非常棒.我只想给那些需要定期完成这项任务的人留一张纸条:将它作为一个rake任务是一个好主意!
LIB /任务/ users_to_csv.rake
# usage:
# rake csv:users:all => export all users to ./user.csv
# rake csv:users:range start=1757 offset=1957 => export users whose id are between 1757 and 1957
# rake csv:users:last number=3 => export last 3 users
require 'csv' # according to your settings, you may or may not need this line
namespace :csv do
namespace :users do
desc "export all users to a csv file"
task :all => :environment do
export_to_csv User.all
end
desc "export users whose id are within a range to a csv file"
task :range => :environment do |task, args|
export_to_csv User.where("id >= ? and id < ?", ENV['start'], ENV['offset'])
end
desc "export last #number users to a csv file"
task :last => :environment do |task, arg|
export_to_csv User.last(ENV['number'].to_i)
end
def export_to_csv(users)
CSV.open("./user.csv", "wb") do |csv|
csv << User.attribute_names
users.each do |user|
csv << user.attributes.values
end
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
这可能偏离了原来的问题,但解决了问题。如果您计划使所有或部分 Active Record 模型能够转换为 csv,则可以使用 ActiveRecord 关注。一个例子如下所示
module Csvable
extend ActiveSupport::Concern
class_methods do
def to_csv(*attributes)
CSV.generate(headers: true) do |csv|
csv << attributes
all.each do |record|
csv << attributes.map { |attr| record.send(attr) }
end
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
提供的属性将用作 CSV 的标头,并且预计该属性对应于所包含类中的方法名称。然后您可以将其包含在您选择的任何 ActiveRecord 类中,在本例中为 User 类
class User
include Csvable
end
Run Code Online (Sandbox Code Playgroud)
用法
User.where(id: [1, 2, 4]).to_csv(:id, :name, :age)
注意:这仅适用于 ActiveRecord 关系,不适用于数组