Ruby on rails возвращает строку, если атрибут модели равен nil

У меня есть модель пользователя, которая имеет один профиль. Профиль имеет такие атрибуты, как имя, пол, возраст, место рождения, обозначение. Поля в профиле не являются обязательными. Пользователь создается администратором только из адреса электронной почты и пароля. Все поля профиля равны нулю, когда пользователь создан. После того, как пользователь создан, он может зарегистрироваться и редактировать свой профиль. Когда мы заходим в профиль пользователя, я хочу показать детали пользователя, а если детали не заданы, я хочу показать "не задано".

Переход к подходу заключается в переопределении атрибутов в модели профиля, например:

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

но это создает много дублирования кода. дела <%= @user.name || 'not set'%> в представлении также приводит к большому дублированию кода.

Я думал о включении "не установлено" в качестве значения по умолчанию для всех атрибутов в миграции, но некоторые поля являются целочисленными и датируются, поэтому это невозможно, и, кроме того, мы не можем добавить перевод.

Я посмотрел на атрибуты ActiveRecord и попытался установить значение по умолчанию для моей строки

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

но это то же самое, что присвоение значения по умолчанию при миграции рельсов и не работает для других типов данных.

Я надеюсь на метод, который может сделать что-то вроде

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

Такие сценарии должны быть довольно распространенными, но я был очень удивлен, не обнаружив вопросов, связанных с этим, здесь, на stackru или в других местах. Я много гуглил, но не смог найти решение. Любые ссылки также приветствуются.

2 ответа

Решение

Может быть, какое-то метапрограммирование?

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

Это может быть извлечено для беспокойства и включать его, где вам это нужно.

Я бы посоветовал не устанавливать настройки по умолчанию в модели. Используйте Presenter/Decorator для отображения значений по умолчанию для целей пользовательского интерфейса.

Это пример 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 

Что касается дублирования: я бы предпочел дублирование метапрограммированию большую часть времени. Проще отлаживать, читать, находить и понимать, ИМХО.

Другие вопросы по тегам