自定义操作视图::解析程序忽略布局



我创建了一个自定义ActionView::Resolver来从数据库而不是文件系统中提取视图。它有效 - 嗯,几乎。它正确地拉取和呈现视图,但它不会在布局中呈现它!基本上,结果是一个只有视图部分(没有布局、样式等)的页面。这是我正在做的事情:

数据库解析器

class DbResolver < ActionView::Resolver
  require "singleton"
  include Singleton
  @@view_handler = ActionView::Template.registered_template_handler(:erb)
  def find_templates(name, prefix, partial, details)
    if (!prefix.empty?)
      pages = Page.where("`controller_name` = :controller_name AND `action_name` = :action_name", { :controller_name => prefix, :action_name => name })
      templates = pages.collect { |page|
        ActionView::Template.new(page.content, "#{page.class} - #{page.id} - #{page.controller_name}/#{page.action_name}", @@view_handler, {
          :format         => "text/html",
          :updated_at     => page.updated_at,
          :virtual_path   => "#{page.controller_name}/#{page.action_name}"
        })
      }
      return templates
    end
  end
end

基础控制器

class BaseController < ApplicationController
  layout "public"
end

联系人控制器

class ContactController < BaseController
  prepend_view_path Page.resolver
  def index
  end
end

require "lib/db_resolver"
class Page < ActiveRecord::Base
  def self.resolver
    return DbResolver.instance
  end
end

为什么我的layout "public"被忽略了?我如何让这个东西停止忽略我的布局?

更新 从日志中,我看到 Rails 确实在尝试查找layouts/public布局 - 但它不在数据库中,我的解析器返回[] .我的理解是,Rails会检查文件系统(默认行为)。但相反,它似乎只是假装一切都很好并继续:

Finding template with: path=about/index; partial=false; details={"formats":["html"],"handlers":["builder","coffee","erb"],"locale":["en"]}
Locating view about/index in database.
Finding template with: path=layouts/about; partial=false; details={"formats":["text/html"],"handlers":["builder","coffee","erb"],"locale":["en"]}
Locating view layouts/about on file system.
Finding template with: path=layouts/public; partial=false; details={"formats":["text/html"],"handlers":["builder","coffee","erb"],"locale":["en"]}
Locating view layouts/public on file system.
Finding template with: path=layouts/public; partial=false; details={"formats":["html","text","js","css","ics","csv","png","jpeg","gif","bmp","tiff","mpeg","xml","rss","atom","yaml","multipart_form","url_encoded_form","json","pdf","zip"],"handlers":["builder","coffee","erb"],"locale":["en"]}
Locating view layouts/public on file system.
Started GET "/about" for 127.0.0.1 at Tue Feb 11 22:05:38 -0500 2014
Processing by AboutController#index as HTML
  [1m[36mPage Load (1.0ms)[0m  [1mSELECT `pages`.* FROM `pages` WHERE (`controller_name` = 'about' AND `action_name` = 'index')[0m
  Rendered Page - 1 - about/index (0.0ms)
Completed 200 OK in 21ms (Views: 19.0ms | ActiveRecord: 1.0ms)

解决了!我真的不知道这甚至是如何导致问题的原因,但是此修复程序有效。我将:format参数设置为 text/html,而不仅仅是html

ActionView::Template.new(page.content, "#{page.class} - #{page.id} - #{page.controller_name}/#{page.action_name}", @@view_handler, {
  :format         => "html",
  :updated_at     => page.updated_at,
  :virtual_path   => "#{page.controller_name}/#{page.action_name}"
})

我将:format => 'text/html'行更改为简单的:format => 'html'.下面是最终的 DbResolver:

class DbResolver < ActionView::Resolver
  @@view_handler = ActionView::Template.registered_template_handler(:erb)
  def initialize(params)
    @exclude_prefixes = (params[:exclude_prefixes] || [])
    super()
  end
  def find_templates(name, prefix, partial, details)
    if (!prefix.empty? && !@exclude_prefixes.include?(prefix))
      pages = Page.where("`controller_name` = :controller_name AND `action_name` = :action_name", { :controller_name => prefix, :action_name => name })
      return pages.collect { |page|
        ActionView::Template.new(page.content, "#{page.class} - #{page.id} - #{page.controller_name}/#{page.action_name}", @@view_handler, {
          :format         => (details[:format] || "html"),
          :updated_at     => page.updated_at,
          :virtual_path   => "#{page.controller_name}/#{page.action_name}"
        })
      }
    end
    return []
  end
end

也许有人可以解释为什么当我创建第一个模板(用于 about/index)时,:format设置"卡住了",然后在解析器尝试查找布局时将相同的格式传递回解析器。我认为这是因为默认情况下,布局应与视图采用相同的格式。我想这是有道理的。

如果 Rails 有一些像样的文档,那就太好了!

相关内容

最新更新