Можно ли автоматически возвращать виртуальные атрибуты в моделях Rails?
Дано:
class Foo
has_one :bar
def bar_name
bar.name
end
end
class Bar
belongs_to :foo
end
В консоли или в представлении я могу @foo.bar_name
получить 'baz'
,
Я знаю, что могу @foo.as_json(methods: :bar_name)
получить {"id"=>"abc123", "bar_name"=>"baz"}
,
Я также мог бы денормализовать атрибут и сделать его не виртуальным, но я бы не хотел этого делать в этом случае.
Можно ли автоматически вернуть модель с включенным виртуальным атрибутом?
#<Foo id: "abc123", bar_name: "baz">
Я хочу сделать это, потому что я создаю большой объект с вложенными коллекциями моделей, и as_json
звонок отвлечен от меня.
2 ответа
Не уверен на 100%, что я понимаю, связано ли ваше беспокойство с as_json
но если это так, это будет работать
class Foo
has_one :bar
def bar_name
bar.name
end
def as_json(options={})
super(options.merge!(methods: :bar_name))
end
end
Теперь вызов @foo.as_json
будет по умолчанию включать bar_name
как ваш явный пример делает.
Гадкий не рекомендовал бы, но вы можете изменить проверку Foo, например #<Foo id: "abc123", bar_name: "baz">
следующее
class Foo
def inspect
base_string = "#<#{self.class.name}:#{self.object_id} "
fields = self.attributes.map {|k,v| "#{k}: #{v.inspect}"}
fields << "bar_name: #{self.bar_name.inspect}"
base_string << fields.join(", ") << ">"
end
end
Тогда "контрольная запись" покажет эту информацию, хотя мне все еще неясно, является ли это вашим намерением, и если да, то почему вы этого хотите.
Вы могли бы использовать attr_accessor
- по документации Rails:
Определяет именованный атрибут для этого модуля, где имя - это symbol.id2name, создавая переменную экземпляра (@name) и соответствующий метод доступа для его чтения. Также создает метод с именем name= для установки атрибута.