2014-02-10 6 views
1

Я пытаюсь показать атрибут модели, только если он присутствует. Если это не так, то должен отображаться местозаполнитель. Это то, что я получил:Как читать атрибут, только если он присутствует?

class Person < ActiveRecord::Base 

    def name 
    if self.name.blank? 
     "[You have no name yet]" 
    else 
     read_attribute(:name) 
    end 
    end 

end 

Однако я получаю ошибку stack level too deep.

Как это можно сделать?

Спасибо за любую помощь.

+0

Если 'read_attribute [...]' 'быть read_attribute (...)'? Фигурные скобки? – Jimbo

+0

@ Jimbo: Это была просто опечатка. Починил это. – Tintin81

ответ

8

Я согласен с Ishank, но вы можете позвонить super использовать поглотитель Rails, а затем использовать presence метод ActiveSupport, который будет возвращать значение, если оно present? или иначе вернуть nil (который будет инициировать заявление после ||) ,

def name 
    super.presence || "[You have no name yet]" 
end 

Чтобы быть ясно, уровень стека слишком глубоко происходит потому, что вы проверяете self.name.blank? - при использовании self.name здесь, что называет name метод на себя (что метод, который вы в настоящее время) - так что приводит к бесконечному циклу.

3

Это не должно быть частью Модели. Вы должны написать этот метод в своих представлениях. Вы можете иметь что-то вроде @person.name || "You have no name yet"

Вы получаете исключение stack level too deep потому что read_attribute[:name] снова вызывает метод name.

0

Можете ли вы попробовать это для стека слишком глубоко?

def name 
    if self.first.name.blank? 
     "[You have no name yet]" 
    else 
     read_attribute[:name] 
    end 
end 
0

Лично я всегда делать что-то вроде этого, используя само [: имя] как способ доступа к базе данных, а не метод .name:

def name 
    if self[:name].blank? 
    "[You have no name yet]" 
    else 
    self[:name] 
    end 
end 

Я до сих пор с помощью реек 2.2, так что это может функция по-разному для вас.

Сказав это, более чистый и более прозрачный способ сделать это - установить «[У вас еще нет имени»] в качестве значения по умолчанию для столбца имен в базе данных. Тогда вам не нужно переопределять метод доступа, который всегда чувствует себя немного грязным для меня.

0

Неправильная практика включает логику представления в модели данных.

Вместо этого вы должны использовать декораторы, просмотреть объекты или аналогичные объекты или просто сделать это в представлении, но не в модели.

Примеры использования гем Draper:

class PersonDecorator < Draper::Decorator 
    delegate_all 

    def name 
    object.name.presence || I18n.t('warnings.no_name_yet') 
    end 
end 

По мнению:

<%= @person.name.presence || I18n.t('warnings.no_name_yet') %> 

Смотрите раздел "Введение" Просмотр объектов в http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/.

1

Также необходимо иметь в виду использование self.Согласно Ruby style guide:

Избегайте self, если это не требуется. (Требуется только при вызове самостоятельной записи аксессор.)

# bad 
def ready? 
    if self.last_reviewed_at > self.last_updated_at 
    self.worker.update(self.content, self.options) 
    self.status = :in_progress 
    end 
    self.status == :verified 
end 

# good 
def ready? 
    if last_reviewed_at > last_updated_at 
    worker.update(content, options) 
    self.status = :in_progress 
    end 
    status == :verified 
end 
Смежные вопросы