формат рендеринга рефакторинга в нескольких контроллерах

поэтому у меня есть метод просмотра в нескольких контроллерах, который в основном выглядит точно так же:

  def show
    show! do |format|
      format.json do
        if @text.activated?
          @text.log
          render_for_api :texts_all, :json => @text
        else
          render :nothing => true
        end
      end
      format.pdf do
        pdf = QrPdf.new(@text)
        send_data pdf.render, filename: "text_#{@text.id}.pdf", type: "application/pdf"
      end
    end
  end

модели для этого разные, но все они имеют одни и те же атрибуты, которые используются в этом методе (activated, log, id). я также мог бы изменить данный хэш render_for_api, из которого в настоящее время texts_all, documents_all и т. д., на хеш, который везде одинаков.

есть ли способ использовать этот код в нескольких моделях без такого огромного дублирования?

я благодарен за каждую подсказку! особенно мне трудно иметь дело с блоком do |format|. но также я не уверен, куда поместить код и как его использовать с разными типами моделей.

благодарю вас.


person choise    schedule 22.01.2012    source источник


Ответы (1)


Если модель действительно универсальна:

def show
  show_model @text
end

Я не уверен, что такое show!, но эту часть вы можете понять. Примерно (не проверено):

def show_model(obj)
  show! do |f|
    f.json do
      return render(:nothing => true) unless obj.activated?

      obj.log
      render_for_api :texts_all, :json => obj
    end

    f.pdf do
      opts = { filename: "text_#{obj.id}.pdf", type: "application/pdf" }
      send_data QrPdf.new(obj).render, opts
    end
  end
end

Что касается того, где живет show_model, я склонен помещать подобные вещи в базовый контроллер или в виде миксина, но могут быть и лучшие варианты. Поскольку у меня обычно есть базовый контроллер, его легко держать там.

person Dave Newton    schedule 22.01.2012
comment
Это был бы и мой ответ! В зависимости от размера/сложности вашего приложения я бы просто добавил его в ApplicationController как частный метод. - person Chris Bailey; 22.01.2012
comment
show! происходит из гема inherited_resources(github.com/josevalim/inherited_resources). Хорошо, как вы думаете, я мог бы поместить его в свой application_controller.rb. каждый контроллер наследуется от этого, хорошая идея? - person choise; 22.01.2012
comment
@choise Там или ваш собственный базовый контроллер - но похоже, что inherited_resources имеет свой собственный базовый класс, поэтому ваш контроллер приложения должен будет расширить его, если он еще этого не сделал. Также не знаю, что делает метод базового класса (методы !), поэтому вам нужно убедиться, что он совместим с произвольными моделями. - person Dave Newton; 22.01.2012