简体   繁体   English

如果模型属性为nil,Ruby on Rails将返回一个字符串

[英]Ruby on rails return a string if a model attribute is nil

I have a user model that has one profile. 我有一个配置文件的用户模型。 The profile has attribute such as name, gender, age, dob, designation. 该配置文件具有名称,性别,年龄,出生日期,名称等属性。 No fields in profile are mandatory. 配置文件中的任何字段都不是必填字段。 The user is created by an admin from only an email address and a password. 该用户仅由管理员通过电子邮件地址和密码创建。 All the profile fields are nil when user is created. 创建用户时,所有配置文件字段均为零。 Once the user is created he can sign up and edit his profile. 创建用户后,他可以注册并编辑其个人资料。 When we go to user profile I want to show the user details and if a detail is not set, I want to show a 'not set'. 当我们转到用户个人资料时,我想显示用户详细信息,如果未设置详细信息,我想显示“未设置”。

The go to approach would be to override the attributes in the profile model like: 可行的方法是覆盖配置文件模型中的属性,例如:

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

but doing so creates a lot of code duplication. 但是这样做会造成很多代码重复。 Doing <%= @user.name || 'not set'%> <%= @user.name || 'not set'%> <%= @user.name || 'not set'%> in the view also results in a lot of code duplication. 视图中的<%= @user.name || 'not set'%>还会导致大量代码重复。

I have thought of including 'not set' as a default value for all the attributes in the migration but some of the fields are integer and date, so its not feasible and moreover we cannot add translation. 我曾考虑过将“未设置”作为迁移中所有属性的默认值,但是某些字段是整数和日期,因此它不可行,而且我们无法添加翻译。

I looked into ActiveRecord Attributes and tried to set the default value to my string 我调查了ActiveRecord属性,并尝试将默认值设置为我的字符串

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

but this is same like assigning the default value in the rails migration and doesn't work for other data types. 但这就像在rails迁移中分配默认值一样,不适用于其他数据类型。

I am hoping for a method that can do something like 我希望有一种方法可以做到

def set_default(attribute)
  attribute || 'not set'
end

Such scenarios must be quite common but I was quite surprised to not find any questions relating to this, here on stackoverflow or other places. 这样的场景一定很普遍,但是我在这里没有发现与此有关的任何问题感到非常惊讶,在stackoverflow或其他地方。 I googled quite a lot but couldn't find a solution. 我在Google上搜索了很多,但找不到解决方案。 Any links are also greatly appreciated. 任何链接也将不胜感激。

Maybe some metaprogramming? 也许一些元编程?

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

This could be extracted to a concern and include it where you need it. 可以将其提取为关注点,并在需要时将其包括在内。

I'd advise against setting a default in the model. 我建议不要在模型中设置默认值。 Use a Presenter/Decorator to display default values for UI purposes. 使用演示者/装饰者来显示用于UI的默认值。

This is a sample for Draper ( https://github.com/drapergem/draper ) but there are other decorator libraries, you could even write a basic decorator without adding a dependency: 这是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 

As for the duplication: i'd prefer duplication over meta-programming most of the time. 至于复制:大多数时候,我宁愿复制而不是元编程。 Easier to debug, read, find and understand, IMHO. 恕我直言,更易于调试,阅读,查找和理解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM