Ruby on rails return 如果模型属性为 nil,则为字符串

Ruby on rails return a string if a model attribute is nil

我有一个只有一个配置文件的用户模型。个人资料具有姓名、性别、年龄、出生日期、职务等属性。个人资料中没有任何字段是必填的。 该用户由管理员仅使用电子邮件地址和密码创建。创建用户时,所有个人资料字段均为零。创建用户后,他可以注册并编辑他的个人资料。当我们转到用户个人资料时,我想显示用户详细信息,如果未设置详细信息,我想显示 'not set'.

首选方法是覆盖配置文件模型中的属性,例如:

def name
  super || 'not set'
end
def age
  super || 'not set'
end
//and so on 

但这样做会产生大量代码重复。 在视图中执行 <%= @user.name || 'not set'%> 也会导致大量代码重复。

我想过将'not set'作为迁移中所有属性的默认值,但有些字段是整数和日期,所以它不可行,而且我们无法添加翻译。

我查看了 ActiveRecord 属性并尝试将默认值设置为我的字符串

class Profile < ApplicationRecord
attribute :name, :string, default: "not set"

但这与在 rails 迁移中分配默认值相同,不适用于其他数据类型。

我希望有一种方法可以做类似

的事情
def set_default(attribute)
  attribute || 'not set'
end

这样的场景一定很常见,但我很惊讶在 Whosebug 或其他地方找不到与此相关的任何问题。我用谷歌搜索了很多但找不到解决方案。任何链接也非常感谢。

也许一些元编程?

class YourModel
  %w(name age).each do |a| # Add needed fields
    define_method(a) do
      super() || 'not set'
    end
  end
end

这可以提取到问题中,并将其包含在您需要的地方。

我建议不要在模型中设置默认值。使用 Presenter/Decorator 显示用于 UI 目的的默认值。

这是 Draper (https://github.com/drapergem/draper) 的示例,但还有其他装饰器库,您甚至可以在不添加依赖项的情况下编写基本装饰器:

class ProfileDecorator < Draper::Decorator
  DEFAULT = "not set".freeze
  def name
    model.name || DEFAULT
  end
end

# and then use it like:

profile.decorate.name 

至于重复:大多数时候我更喜欢重复而不是元编程。恕我直言,更容易调试、阅读、查找和理解。