Rails并将控制台查询导出到csv

时间:2017-10-30 14:39:47

标签: ruby-on-rails csv

我正在运行以下查询...

require 'csv'
require File.dirname(__FILE__) + '/config/environment.rb'

file = "#{Rails.root}/public/data.csv"
registrations = OnlineCourseRegistration.where(course_class_id: 681).where(status: "Completed").where("score >= ?", "80").where("exam_completed_at BETWEEN ? AND ?", 3.years.ago, Date.today)

CSV.open( file, 'w' ) do |writer|
  writer << registrations.first.attributes.map { |a,v| a }
  registrations.each do |s|
    if s.user_id
        writer << User.find(s.user_id).email
    end
    writer << s.attributes.map { |a,v| v }
  end
end

这行writer << User.find(s.user_id).email失败并显示错误:

`<<': undefined method `map' for "my_user@yahoo.com":String (NoMethodError)`

基本上,我只想添加一个包含用户电子邮件地址的列。

更新

以下是电子邮件字段中的当前输出

id  cart_id user_id course_class_id created_at  updated_at  exam_attempts   exam_completed_at   evaluation_completed_at status  score   add_extension   retest_cart_id  retest_purchased_at
11990   10278   6073    681 2014-10-30 20:34:18 UTC 2014-12-17 14:48:39 UTC 2   2014-12-17 03:16:44 UTC 2014-12-17 14:48:39 UTC Completed   90  FALSE       
11931   10178   6023    681 2014-09-02 22:35:08 UTC 2015-02-24 03:58:03 UTC 1   2015-02-24 03:56:12 UTC 2015-02-24 03:58:03 UTC Completed   80  FALSE       
12015   10316   6089    681 2014-11-15 14:31:05 UTC 2014-11-18 20:14:13 UTC 1   2014-11-18 20:11:46 UTC 2014-11-18 20:14:13 UTC Completed   82  FALSE       
12044   10358   6103    681 2014-12-03 15:56:39 UTC 2014-12-06 23:05:18 UTC 2   2014-12-06 23:02:13 UTC 2014-12-06 23:05:18 UTC Completed   94  FALSE       

所以我想在上面的每个列中添加一个电子邮件字段。

4 个答案:

答案 0 :(得分:1)

我不使用CSV,但我推断writer <<map右侧的<<调用map。字符串不响应User.find(s.user_id).email。并且,array是一个字符串。所以你得到了错误。

我想您可以构建包含电子邮件地址的writer << array_with_email_in_correct_location ,然后致电:

Sub Data_Validation_Critical()

    'Critical:
    Range("B4").Select
        With Selection.Validation
        .Delete
        .Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
        xlBetween, Formula1:="=DVEmergentCritical"
        .IgnoreBlank = True
        .InCellDropdown = True
        .InputTitle = ""
        .ErrorTitle = "ERROR: Invalid Selection"
        .InputMessage = "Y or N"
        .ErrorMessage = _
        "You have entered and invalid seleciton. Please select Y or N."
        .ShowInput = True
        .ShowError = True
    End With

End Sub

就可以了。但这看起来很奇怪,因为我觉得你最后只有一个电子邮件地址。除非那是你想要的。

没有看到一些样本数据和期望的结果,很难说。

答案 1 :(得分:1)

这是非常贫民窟。但是完全披露,这是客户要求的特别报告,它可以满足他们的需求。我只是将[User.find(s.user_id).email]连同到writer语句。看起来简单地用它包围它就足以完成这个伎俩了。这是完整的代码......

require 'csv'
require File.dirname(__FILE__) + '/config/environment.rb'

file = "#{Rails.root}/public/data.csv"

registrations = OnlineCourseRegistration.where(course_class_id: 681).where(status: "Completed").where("score >= ?", "80").where("exam_completed_at BETWEEN ? AND ?", 3.years.ago, Date.today)

CSV.open( file, 'w' ) do |writer|
  writer << registrations.first.attributes.map { |a,v| a }
  registrations.each do |s|

    writer << s.attributes.map { |a,v| v } + [User.find(s.user_id).email]
  end
end

答案 2 :(得分:0)

sumregistrations.first.attributes是字符串。

s类没有String方法

如果您需要更多帮助,请添加更多信息

答案 3 :(得分:0)

首先确保您已定义关联并使用它:

class OnlineCourseRegistration
  belongs_to :user
end

class User
  has_many :online_course_registrations
end

您的代码的一个主要问题是:

User.find(s.user_id)

online_course_registrations返回的每行会导致一个额外的数据库查询,这非常慢。

所以你想加入行。

registrations = OnlineCourseRegistration.where(course_class_id: 681)
                                        .joins(:user)
                                        .where(status: "Completed")
                                        .where("score >= ?", "80")
                                        .where(exam_completed_at: (3.years.ago.. Date.today))

您可以通过执行以下操作获取属性和用户电子邮件:

registrations.map do |r|
  r.attributes.values << r.user.email
end

attributes返回哈希值。 Hash#values将值作为数组返回。然后,我们将电子邮件推送到阵列的末尾。容易腻。

但是首先使用.pluck直接从数据库获取值会更有效:

columns = OnlineCourseRegistration.column_names.map {|c| "#{OnlineCourseRegistration.table_name}.#{c}" }.push('users.email')

registrations = OnlineCourseRegistration.where(course_class_id: 681)
                                        .joins(:user)
                                        .where(status: "Completed")
                                        .where("score >= ?", "80")
                                        .where(exam_completed_at: (3.years.ago.. Date.today))
registrations.pluck(*columns)

要输出到csv,您可以这样做:

CSV.open( file, 'w' ) do |csv|
  registrations.each {|r| csv << r }
end