Skip to content

Instantly share code, notes, and snippets.

@nnabeyang
Created July 29, 2012 16:04
Show Gist options
  • Save nnabeyang/3199911 to your computer and use it in GitHub Desktop.
Save nnabeyang/3199911 to your computer and use it in GitHub Desktop.
railsのコントローラーとビューの連携はこんな感じ
require 'erb'
class ERB
def self.call(source)
new(source, nil, nil, '@output_buffer').src
end
end
class Template
def initialize(source, path)
@path = path
@source = source
end
def render(view)
compile(view)
view.send(method_name)
end
def compile(view)
mod = view.singleton_class
code = ERB.call(@source)
mod.module_eval(<<-RUBY
def #{method_name}
#{code}
@output_buffer
end
RUBY
)
end
def method_name
"_#{@path.gsub(/[^a-z_]/, '_')}"
end
end
class Controller
attr_accessor :response_body
def view_context_class
helpers = _helpers if respond_to?(:_helpers)
@view_context_class ||= Class.new(Object) do
include helpers
end
end
def view_context
view_context_class.new
end
def render(path)
template = Template.new(File.binread(path), path)
@response_body = template.render(view_context)
end
end
<% (1..3).each do|i| %>
<%= i%>
<% end %>
<%= say_hello("world") %>
#!/usr/bin/ruby -I.
require 'test/unit'
require 'controller_and_view'
module HelloHelper
def say_hello name
"hello, #{name}"
end
end
class HelloController < Controller
def _helpers
HelloHelper
end
end
class ActionViewTests < Test::Unit::TestCase
def test_controller_render
controller = HelloController.new
controller.render("hello.txt.erb")
assert_equal "hello, world\n", controller.response_body
end
def test_template_render
controller = HelloController.new
view = controller.view_context
path = "./hello.txt.erb"
Template.new(File.binread(path), path).compile(view)
path = "./each.txt.erb"
Template.new(File.binread(path), path).compile(view)
assert_equal "hello, world\n", view.send("___hello_txt_erb")
assert_equal "\n1\n\n2\n\n3\n\n", view.send("___each_txt_erb")
end
def test_template_method_name
template = Template.new("", "./hello.txt.erb")
assert_equal "___hello_txt_erb", template.method_name
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment