2016-10-04 4 views
0

Я пытаюсь интерполировать шаблон ERB из нескольких объектов в Ruby. Он отлично работает, если источником переменных является один класс. Каков наилучший способ сделать интерполяцию, когда ERB содержит переменные, присутствующие в разных классах.Binding ERB Template от более чем одного класса

Вот версия полосы вниз, что я пытаюсь достичь:

#!/usr/bin/ruby 

require 'erb' 
require 'pp' 

class Person 
    attr_reader :first_name, :last_name 

    def initialize(first_name, last_name) 
    @first_name = first_name 
    @last_name = last_name 
    end 

end 

class Animal 
    attr_reader :animal_type 

    def initialize(type) 
    @animal_type = type 
    end 

end 

person = Person.new("John", "Doe") 
animal = Animal.new("doggie") 

template = "<%=first_name%> <%=last_name%> has a <%=type%>" 

puts ERB.new(template).result(person.instance_eval { binding }) 

выше завершаться undefined local variable or method 'type' который является правильным, поскольку этот атрибут относится к объекту класса животных.

Одна работа, которую я нашел, - это создать хеши и использовать слияние, чтобы свести их к одному, но это означало бы много изменений в существующем коде. Есть ли лучший способ достичь этого?

ответ

1

Вы можете использовать openstruct, чтобы упростить слияние атрибутов, поэтому вам не нужно переписывать шаблоны.

# in config/application.rb 
require 'ostruct' 

# in the file where you compile ERB 
person = OpenStruct.new Person.new("John", "Doe").attributes 
person.type = animal.type 

С OpenStruct ваш объект будет хэш, но такие методы, как person.first_name все равно будет работать. И вы можете добавить произвольные ключи-валы, чтобы вы могли сделать person.type вернуть любое значение, которое вы хотите.

+0

Спасибо за приятную альтернативу. Я не уверен, насколько это масштабируемо, если мне придется писать каждый хэш-атрибут отдельно. Например, что, если бы у меня было 10 атрибутов вместо 1 animal_type. –

+0

возможно 'OpenStruct.new (person.attributes.merge (animal.attributes))', но проблема в том, что если у вас есть атрибуты с именем одинаковые (например, id или created_at). –