2016-09-02 3 views
0

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

До сих пор я нашел это Rails : post-processing a rendered view, в котором показано, как визуализировать вид в виде строки. - Ницца.

Поскольку у меня есть базовый контроллер, я подумывал добавить какой-то фильтр before_render, который передал бы мне rendered_string, чтобы я мог его заменить, а затем отрисовать оттуда. Здесь я застрял, и теперь я думаю, возможно ли это. Некоторый код высокого уровня выглядит следующим образом:

class BaseClass 
    before_render :replace_some_key_words 

    def replace_some_key_words(rendered_string) 
    render rendered_string.sub! 'foo', 'bar' 
    end 

(я нашел реализацию before_render в http://qiita.com/cryeo/items/d116192fb355411f9008, но я просто просто не прийти на рельсы, чтобы понять, что я хочу, это возможно от этого)

благодарными для всех предложений.

+0

Обратный путь (рельсы 1.x), вы можете сделать это с помощью after_filter - не знаете, работает ли он (мы используем для рендеринга xml из приложения rails и используем фильтр after, чтобы переписать ответ как html с xslt) –

ответ

0

Что делать, если вы попробовали промежуточное программное обеспечение для стойки? Вопросы here, here и here, похоже, имеют ответы, которые используют этот подход. С Rails 4.5 я нашел, что body из Rack::Response является неизменным, поэтому этот answer оказался особенно полезным. Вот код, который я закончил с:

module AfterRender 
    require 'rack' 
    CONTENT_LENGTH = 'Content-Length' 

    class SanitizeResponse 
    def initialize(app) 
     @app=app 
    end 

    def call(env) 
     status, headers, response = @app.call(env) 
     if response.present? and response.respond_to? :body 
     new_response_body = sanitize_body(response.body) 
     headers[CONTENT_LENGTH] = new_response_body.length.to_s if headers[CONTENT_LENGTH].present? 
     new_response = Rack::Response.new([new_response_body], status, headers) 
     return [status, headers, new_response] 
     end 
     return [status, headers, response] 
    end 

    def sanitizeBody(body) 
     to_ret = body.dup 
     to_ret.gsub!('string_to_be_replaced', 'replacement_string') 
     to_ret 
    end 
    end 
end 

проверить, что response.body определяется чтобы убедиться в отсутствии funkiness происходит при отправке через файлы для моего углового приложения (они используют Sprockets::Asset вместо Rack::Response). Во всяком случае, я не хочу санировать эти файлы. Мы также только сбросили headers['Content-Length'], если он уже был определен, что маловероятно, если Transfer-Encoding разрывается. new_response может быть просто массивом (например, [new_response_body]), но я считаю безопаснее отправлять response так же, как он появился, как Rack::Response. Это documentation полезно для понимания того, как должно быть сформировано возвращение call (т. Е. В виде массива).

Чтобы убедиться, что это промежуточное программное обеспечение действительно используется, я поместил его в новый файл, который находится по адресу app/middleware/after_render.rb. В моем config/application.rb я добавил require_relative '../app/middleware/after_render.rb' наверху и config.middleware.use AfterRender::SanitizeResponse в классе Application. Это выглядит примерно так:

require File.expand_path('../boot', __FILE__) 
require_relative '../app/middleware/after_render.rb' 

require 'rails/all' 

module MyModule 
    class Application < Rails::Application 
    config.autoload_paths << "#{Rails.root}/app" 
    config.middleware.use AfterRender::SanitizeResponse 
    end 
end 

Надеюсь, это поможет!

Смежные вопросы