2012-01-06 4 views
4

У меня есть модель пользователя со столбцом состояния. Вместо того, чтобы делать сравнения строк каждый раз, как этотActiveSupport :: StringInquirer in Rails

user.status == 'verified' 

я, хотя я должен делать

user.status.verified? 

Так что я добавил следующий код

def status 
    ActiveSupport::StringInquirer.new(self.status) 
    end 

Но теперь я получаю уровень стека слишком глубокий, который понятно. Как это исправить?

Я использую Rails 3.2.

ответ

15

Ваша проблема заключается в том, что вы вызываете status внутри метода status, что вызывает проблему с бесконечной рекурсией.

Большинство ответов здесь сосредоточены на использовании ActiveSupport :: StringInquirer инициализатор, как это:

def status 
    return unless self['status'] 
    ActiveSupport::StringInquirer.new(self['status']) 
end 

Но вам не нужно. ActiveSupport добавляет запрос метод для всех строк, так что вы можете сделать это так:

def status 
    self['status'].try(:inquiry) 
end 

Это то же самое, как с помощью read_attribute:

def status 
    read_attribute(:status).try(:inquiry) 
end 

Или вы можете просто позвонить супер:

def status 
    super.try(:inquiry) 
end 
+0

очень полный ответ! – caesarsol

2

Используйте следующий код, чтобы предотвратить «уровень стека слишком глубоко» ошибка:

def status 
    ActiveSupport::StringInquirer.new(self['status']) 
end 
2

Вы можете прочитать в разделе «перезаписывающие аксессоров по умолчанию» в ActiveRecord :: документация Базы: http://api.rubyonrails.org/classes/ActiveRecord/Base.html

По сути, вы будете использовать read_attribute и write_attribute (или self ['attribute'], например, Baldrick) для доступа к базовому атрибуту без вызова метода доступа к атрибутам.

0

Принятый ответ не обрабатывает случай, когда атрибут равен нулю. Это лучше:

def status 
    (read_attribute(:status) || "").inquiry 
end