Rabl.render: как использовать вспомогательные методы просмотра?

Я использую Rabl для генерации вывода XML в задаче rake:

xml = Rabl.render @listings, 'feeds/listings', :format => :xml
# do stuff with xml

Однако мне нужно использовать несколько вспомогательных методов в указанном файле представления rabl, и я продолжаю получать NoMethodError, как и ожидал из ответа на этот вопрос.

Я пытался использовать extends и include в классе, используемом задачей rake, но все равно получаю ту же ошибку во вспомогательных методах:

require "#{Rails.root}/app/helpers/feeds_helper.rb"

class SerializeData
  extends FeedsHelper

  def perform
    xml = Rabl.render @listings, 'feeds/listings', :format => :xml
    # do stuff with xml
  end
end

Мой вопрос: есть ли способ использовать вспомогательные методы в файлах представления rabl, сгенерированных таким образом? (или, по крайней мере, таким образом, чтобы я все еще мог отображать их в виде строки в задаче rake?) Вспомогательные методы используются много, много раз для правильного форматирования различных данных в соответствии с фиксированными требованиями, поэтому было бы очень трудно удалить их полностью .


person eirikir    schedule 06.08.2013    source источник


Ответы (3)


В итоге я получил решение с обезьяньими пятнами.

Я заметил, что ошибка NoMethodFound исходила от экземпляра класса Rabl::Engine, поэтому я включил необходимые методы маршрутизации и вспомогательные методы в этот класс, после чего смог получить к ним доступ:

require "#{Rails.root}/app/helpers/feeds_helper.rb"
...
class Rabl::Engine
  include Rails.application.routes.url_helpers
  include FeedsHelper
end

Также обратите внимание, что хост URL должен быть установлен, если вы используете url в дополнение к path помощникам (например, root_url и root_path):

Rails.application.routes.default_url_options[:host] = "www.example.com"

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

person eirikir    schedule 08.08.2013

Вы можете передать объект области с параметром области. Итак, если у вас есть доступ к объекту с включенным помощником, например, в контексте представления, вы можете передать это, например:

<%= Rabl::Renderer.json(object_to_render, 'api/v1/object/show', view_path: 'app/views', scope: self).html_safe%>

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

class RakeScope
  include FeedHelper
end

Rabl::Renderer.json(object_to_render, 'api/v1/object/show', view_path: 'app/views', scope: RakeScope.new() )

Второй вариант не пробовал, но первый работает отлично.

person toxaq    schedule 10.11.2013

Хотя это и не совсем та же проблема, у меня была аналогичная проблема с доступом к помощникам из спецификаций RSpec. Я создал вспомогательную функцию, которая создает область, которую вы можете использовать для добавления любых необходимых вам помощников. Следующее дало мне доступ к вспомогательным методам пути и URL-адреса, и что-то подобное должно работать для Rake.

#spec/support/rabl_helper.rb
def render_rabl(object, options={})
  options = {
    format:    'json',
    view_path: 'app/views',
    file:      example.example_group.top_level_description,
    scope:     RablScope.new
  }.merge(options)

  result = Rabl.render(object, options.delete(:file), options)
  options[:format] == 'json' ? JSON.parse(result) : result
end

class RablScope
  include Rails.application.routes.url_helpers
end
person Declan Whelan    schedule 16.01.2014