【发布时间】:2021-03-02 03:58:59
【问题描述】:
我想编写一个简单的 erb 模板生成器,以使用 Generator 模块从视图中解析存储的 erb 模板。我从 rails 控制器调用 Generator 来生成它的单例实例,并通过 self 指针将 WallController 传递给它。
require 'generator'
class WallController < ApplicationController
def index
header = File.read 'app/views/application-header.html'.freeze
@instances = {header: header}
# Load view generators
Generator.generate_instances self
end
end
Generator.generate_instances 实际上尝试做的第一件事是复制 WallController 实例变量(因此是自指针)以执行对 erb 模板的正确解析。然后它生成返回 erb 结果文本的方法。
require 'erb'
module Generator
def self.generate_instances environment
# Mimic class environment
if environment.superclass == ApplicationController
environment.instance_variables.each do |v|
puts "Copy instance variable '#{v}' from #{environment.name} to #{self.name}"
value = environment.instance_variable_get(v)
self.send :instance_variable_set, v, value
end
end
# Parse the ERB templates
templates = @instances
return 0 if !templates.is_a?(Hash) or templates.empty?
templates.keys.each.with_index do |key, index|
define_singleton_method key do
ERB.new(templates.values[index]).result
end
end
end
end
Generator 接口的用法如下所示:
<%=== Generator.header %>
我是 Rails 新手,但我发现 Rails 控制器包含的文件仅限于单个静态结构。我没有设法覆盖 class Object 或 class Class 可能有用的单例方法。
但是,在运行上述示例后,WallController 的实例变量返回 WallController 类地址,而不是 WallController.index 定义的值。
undefined method `empty?' for #<WallController:0x000000000a1f90>
是否有正确的方法在其他控制器之间分配 rails 控制器实例变量?如果不是,为什么常规实例副本不起作用?
如果我必须用 ruby 编写它,那将很容易:
module Y
def self.generate_environment environment
environment.instance_variables.each do |v|
puts "Copy #{v} from #{environment.name} to #{self.name}"
value = environment.instance_variable_get v
self.instance_variable_set(v, value)
end if environment.class == Class
puts "Retrived string: #{@hello}"
end
end
class X
def self.index
@hello = 'Hello, World!'
Y.generate_environment self
end
end
X.index
【问题讨论】:
-
您将
WallController的实例作为environment传递给Generator.generate_instances,然后检查该实例是否为Class和environment == Class。environment == Class总是会失败,所以你最终不会复制任何实例变量。 -
哦,谢谢。错误的错字。我现在在问题中解决了这个问题。
-
你仍在传递
self,它是一个实例,然后检查env.class == Class,它是否为假,因为self是WallController -
WallController.class == class,这是真的。 -
但是,为了更具体,我将其更改为
environment.superclass == ApplicationController。
标签: ruby-on-rails ruby controller erb