Rails рендеринг партиала json в модели

В нашем приложении rails 3.2 мы используем Jbuilder для рендеринга наших ответов json (здесь ничего особенного). Представление json может быть таким простым:

_model_name.json.jbuilder

json.extract!(page, :id, :name, :url_name)

Нам часто нужно возвращать глубоко вложенный объект json, и частичные файлы Jbuilder отлично подходят для этого:

_page.json.jbuilder

json.extract!(page, :id, :name, :url_name)
json.page_images (page_images) do |json, page_image|
    json.partial! page_image
end

В последнем примере будет получена страница и вложенные изображения page_images, представление json ... снова ничего особенного.

Часто один партиал вызывает другой и может возвращать вложенный объект json на 2 или 3 уровня глубиной.

ПРОБЛЕМА

Как я уже упоминал выше, мы используем партиалы Jbuilder, чтобы быстро связать несколько партиалов вместе, чтобы сформировать глубоко вложенный объект json для представления. Нам также нужно создать те же самые вложенные объекты, что и хэш (а не json), И сделать их доступными для модели.

С помощью атрибутов .attributes легко заставить объект Jbuilder выводить хэш! метод, но у нас есть серьезные трудности с предоставлением JBuilder доступа к частичным представлениям модели.

Глядя на исходный код Jbuilder, похоже, что классу JbuilderTemplate требуется доступ к контексту контроллера, чтобы все работало.

Мы могли бы попробовать что-то вроде этого:

class SomeClass

  def initialize pages
    @pages = pages
    @context = ActionController::Base.new
  end

  def to_hash
     builder = JbuilderTemplate.new(@context)
     builder.pages(@pages) do |json, page|
        json.partial! page
     end
     builder.attributes!
  end
end

Приведенный выше пример явно неверен, но он показывает, что нужно делать. Я просто не уверен, как передать инициализацию контроллера из модели, а затем передать контекст контроллера.

Некоторые отведения, которым мы следуем:

Может ли кто-нибудь помочь нам указать правильное направление?


person Erik Lott    schedule 10.02.2012    source источник


Ответы (4)


Я почти уверен, что вы здесь на правильном пути. Вы должны иметь возможность вызвать json.array! и построить партиал в обычном режиме, если вы передадите блок непосредственно в инициализатор.

def to_hash
  builder = JbuilderTemplate.new(@context) do |json|
    json.array! @pages, partial: 'path/to/partial'
  end
  builder.attributes!
end
person Jimmy Lien    schedule 22.06.2016

Не нашел решения. Мы вернулись к использованию as_json для настройки вывода json нашей модели.

person Erik Lott    schedule 11.02.2012
comment
Посмотрите мой ответ ниже, если вы все еще хотите иметь возможность повторно использовать ваши шаблоны jbuilder. - person Jimmy Lien; 30.06.2016

Я использую ActiveModel :: Serializer, чтобы сделать то же самое. Вы можете отобразить json в модели или где угодно - мы делаем это для предварительного заполнения кеша.

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

ItemSerializer.new(item).to_json
person Mark Swardstrom    schedule 21.06.2013

Если вам действительно нужна эта функция, я могу показать вам прокладку:

c = ActionController::Base.new
c.instance_variable_set '@item', Item.find(5)
JSON.parse c.render_to_string('items/show')
person sandrew    schedule 15.01.2014