Доступ к Ruby-аксессорам с помощью блочных переменных - PullRequest
1 голос
/ 22 января 2010

У меня есть приложение, которое я использую 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

Есть ли способ, которым я могу сделать это правильно? По сути, моя цель состоит в том, чтобы создать хеш из значений, которые хранятся в столбцах таблицы, любой ввод приветствуется.

Ответы [ 4 ]

3 голосов
/ 22 января 2010
  • Ruby программисты обычно делают отступ 2
  • Ваш код объединял все электронные письма в одну запись хеша, а не запись в электронном письме.
  • Если вы хотите вызвать метод динамически, используйте 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

Ключевым элементом является «send», который вызывает метод, идентифицируемый строкой или символом.

2 голосов
/ 22 января 2010

Вы не можете иметь переменную итератора, начинающуюся с @. Попробуйте что-то вроде этого:

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
1 голос
/ 22 января 2010

В дополнение к комментарию Блинри, строка

@emailhash[email.ticketno] || Hash.new

выглядит подозрительно. Вы уверены, что не хотите

@emailhash[email.ticketno] ||= Hash.new

0 голосов
/ 22 января 2010

Помимо предыдущих точных наблюдений, я хотел бы добавить следующее:

Точка 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...