我试图仅在模型属性存在时才显示它。如果不是,则应显示占位符。这就是我所拥有的:
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 :(得分: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/中的“介绍视图对象”部分。