如果只有它存在,如何读取属性?

时间:2014-02-10 12:10:34

标签: ruby-on-rails ruby

我试图仅在模型属性存在时才显示它。如果不是,则应显示占位符。这就是我所拥有的:

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错误。

如何做到这一点?

感谢您的帮助。

6 个答案:

答案 0 :(得分:8)

我同意Ishank,但您可以调用super来使用Rails的getter,然后使用ActiveSupport的presence方法,如果它是present?则返回值,否则返回{{1 (}将触发nil之后的语句。

||

要清楚,堆栈级别太深了,因为您正在检查def name super.presence || "[You have no name yet]" end - 当您在此处使用self.name.blank?时,即在自己上调用self.name方法(这是方法)你当前在 - )因此导致无限循环。

答案 1 :(得分:3)

这不应该是Model的一部分。您应该在视图中编写此方法。 您可以使用@person.name || "You have no name yet"

之类的内容

您将获得例外stack level too deep,因为read_attribute[:name]再次调用name方法。

答案 2 :(得分:1)

使用self时要注意的事项。根据{{​​3}}:

  

避免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

答案 3 :(得分:0)

你可以试试这个堆栈太深了吗?

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

答案 4 :(得分:0)

就个人而言,我总是这样做,使用self [:name]作为访问数据库的方式,而不是.name方法:

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

我仍在使用rails 2.2,所以这对你来说可能有所不同。

话虽如此,更简洁,更透明的方法是将“[你还没有名字]”设置为数据库中名称列的默认值。然后你不需要覆盖访问器方法,这对我来说总是让人觉得有点脏。

答案 5 :(得分:0)

在数据模型中包含表示逻辑不是一个好习惯。

您应该使用装饰器,视图对象或类似物,或者只是在视图中进行,而不是在模型中。

使用Draper gem的示例:

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/中的“介绍视图对象”部分。