我有一个应用程序,我使用Active Record来访问数据库。我正在尝试获取信息并将其放入哈希值以供以后使用。
这基本上就是我在做什么。
require 'active_support'
@emailhash = Hash.new
emails = Email.find(:all)
emails.each do |email|
email.attributes.keys.each do |@column|
@emailhash[email.ticketno] || Hash.new
@emailhash[email.ticketno] = email.@column
end
end
不起作用的行是:
@emailhash[email.ticketno] = email.@column
有什么方法可以做到这一点吗?基本上我的目标是建立一个存储在表列中的值的哈希值,欣赏任何输入。
答案 0 :(得分:3)
Object.send
。@emailhash[email.ticketno] || Hash.new
没有做任何事。这样的事可能会这样做:
require 'active_support'
@emailhash = {}
Email.find(:all).each do |email|
@mailhash[email.ticketno] = {}
email.attributes.keys.each do |key|
@emailhash[email.ticketno][key] = email.send(key)
end
end
关键部分是“发送”,它调用由字符串或符号标识的方法。
答案 1 :(得分:2)
你不能以@开头的迭代器变量。尝试这样的事情:
require 'active_support'
@emailhash = Hash.new
emails = Email.find(:all)
emails.each do |email|
@emailhash[email.ticketno] = email.attributes.keys.collect{|key| key.column}
end
答案 2 :(得分:1)
除了blinry的评论,该行
@emailhash[email.ticketno] || Hash.new
看起来很可疑。你确定你不想要
@emailhash[email.ticketno] ||= Hash.new
答案 3 :(得分:0)
除了之前的准确观察,我想补充以下内容:
第1点。
重要的是要声明@ivars
可能不适用于正式的函数参数...这就是说,我认为它是无效的:
collection.each { |@not_valid| }
在块内部使用@ivars
也是一种不好的做法,您不会确定该块将在哪个上下文中执行(众所周知,该块内的self
引用可能与其外的self
引用不同。)
第2点。
您应该记住的另一点是,如果您不指定(||)运算符的结果,则根本不会进行任何修改(只是浪费时间),但您可以使用:
mail_hash[email.ticketno] = mail_hash[email.ticketno] || Hash.new
这很容易改写为:
mail_hash[email.ticketno] ||= Hash.new
第3点。
即使email.attributes.keys
是一个廉价的指令,也不是免费的......我建议在迭代块之外有这个(假设我们没有使用文档数据库,每个记录的密钥总是相同的) 。
最终结果
require 'active_support'
mails = Email.all
@mailshash = mails.inject(Hash.new) do |hsh, mail|
# mail.attributes is already a representation of the
# email record in a hash
hsh[mail.ticketno] = mail.attributes
hsh
end