有没有办法预先构建页面缓存而不通过http请求调用实际页面?
我查看了this和this等解决方案,但这些解决方案并未生成缓存。
我有一个相对复杂的视图,并希望缓存整个事情。我想在应用程序中预先构建这个缓存版本,这样当用户实际点击它时,它就已经存在了。
由于
答案 0 :(得分:2)
我们需要从rake任务中做类似的事情 - 我们有一部分需要显示一个很长的实体列表(~700),这些实体在某种程度上是特定于上下文的,并且由于一系列数据库结构问题和自定义排序标准,很容易采取>在进入缓存之前第一次渲染25秒>这通常会超时,因为我们的HTTP服务器设置为在30秒后终止HTTP请求而没有响应,并且预先缓存此自定义列表是一种解决方案。
如果需要辅助方法或其他实体,则需要创建ActiveController :: Base或其中一个控制器的实例,然后将其lookup_context引用传递给ActionView.Renderer的新实例。
在我们的rake任务中,我们做了以下
namespace :rake_for_time_consuming_nonsense do
task :pre_cache_long_list do
PreCacher.pre_fetch_partials
end
end
class PreCacher
def self.pre_fetch_partials
the_controller = ActionController::Base.new
# Set any instance variables required by your partial in the controller,
# they will be passed to the partial with the view_context reference
the_controller.instance_variable_set "@cache_key", cache_key
the_controller.instance_variable_set "@the_object", MyModel.first
view_renderer = ActionView::Renderer.new the_controller.lookup_context
view_renderer.render the_controller.view_context, {partial: 'my_model/the_partial', layout: false}
end
end
这适用于Rails 3.2.13。
答案 1 :(得分:0)
我认为以下链接应该会给你一个良好的开端。 How do I get the rendered output of a controller's action without visiting the web page?
我尝试完成同样的操作,到目前为止我可以看到,您的虚假请求应该有正确的主机,因为缓存键包含主机信息。
我使用ActionController :: Integration :: Session
完成了缓存ais = ActionController::Integration::Session.new
ais.host = host
ais.xml_http_request(:post, url, params, headers)
我还有另外一个:
class FakeRequest
include ActionController::UrlWriter
def initialize(url, params, session, host)
@url = url
@params = params
@session = session
default_url_options[:host] = URI.parse(host).host
end
def post
process(:post)
end
def get
process(:get)
end
def xhr
process(:post, true)
end
def process(method, ajax = false)
uri = URI.parse(url_for(@url))
request = ActionController::TestRequest.new({'HTTP_HOST' => uri.host,'rack.input' => '','rack.url_scheme' => 'http'})
request.query_parameters = @params
request.path = uri.path
request.host = uri.host
request.env['REQUEST_METHOD'] = method.to_s.upcase
if ajax
request.headers['X-Requested-With'] = 'XMLHttpRequest'
end
@session.each_pair do |k,v|
request.session[k] = v
end
response = ActionController::TestResponse.new
controller = ActionController::Routing::Routes.recognize(request).new
return controller.process(request, response)
end
end
这也将返回响应对象。