我正在运行以下查询...
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
所以我想在上面的每个列中添加一个电子邮件字段。
答案 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)
sum
或registrations.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