Skip to content

Commit

Permalink
Merge pull request #195 from jphager2/issue-96
Browse files Browse the repository at this point in the history
Issue 96
  • Loading branch information
bryanp committed Sep 21, 2016
2 parents 436b1c6 + 6c48c57 commit c1da172
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 0 deletions.
1 change: 1 addition & 0 deletions pakyow-presenter/lib/pakyow/presenter/base.rb
Expand Up @@ -2,6 +2,7 @@

require 'pakyow/presenter/view_store'
require 'pakyow/presenter/view'
require 'pakyow/presenter/form'
require 'pakyow/presenter/template'
require 'pakyow/presenter/page'
require 'pakyow/presenter/container'
Expand Down
64 changes: 64 additions & 0 deletions pakyow-presenter/lib/pakyow/presenter/form.rb
@@ -0,0 +1,64 @@
module Pakyow
module Presenter
class Form
attr_reader :view, :context

PATCH_METHOD_INPUT = <<-HTML
<input type="hidden" name="_method" value="patch">
HTML

def initialize(view, context)
@view = view
@context = context
end

def create(*binding_args, &block)
bind_form_action(binding_args, block) do |view|
view.attrs.action = routes.path(:create, request_params) if routes
end
end

def update(*binding_args, &block)
bind_form_action(binding_args, block) do |view|
if routes
route_params = request_params.merge(
:"#{scoped_as}_id" => view.attrs.__send__('data-id').value
)

view.attrs.action = routes.path(:update, route_params)
end

view.prepend(View.new(PATCH_METHOD_INPUT))
end
end

private

def bind_form_action(binding_args, block)
data = binding_args.first

view.bind(binding_args) { |view, _| yield(view) }

return if block.nil?

if block.arity == 1
view.instance_exec(data, &block)
else
block.call(view, data)
end
end

def routes
@routes ||= Router.instance.group(scoped_as)
end

def scoped_as
view.scoped_as
end

def request_params
context.request.params
end
end
end
end
5 changes: 5 additions & 0 deletions pakyow-presenter/lib/pakyow/presenter/view_context.rb
Expand Up @@ -59,6 +59,11 @@ def subject
end
end

def form(*scope_args)
view = scope(*scope_args).subject
Form.new(view, context)
end

# Pass these through, handling the return value.
#
def method_missing(method, *args, &block)
Expand Down
Expand Up @@ -14,6 +14,64 @@
D
}

let(:router) { Pakyow::Router.instance }
let(:group) { Pakyow::Router.instance.group(:foo) }
let(:request) { mock_request }
let(:app_context) { Pakyow::AppContext.new(request, nil) }
let(:view_context) { Pakyow::Presenter::ViewContext.new(view, app_context) }

context 'when creating a form' do
it 'sets the action' do
expect(request).to receive(:params) { {} }
expect(group).to receive(:path) { '/foo' }.with(:create, {})
expect(router).to receive(:group) { group }.with(:foo)

view_context.form(:foo).create({})
expect(view.scope(:foo).first.instance_variable_get(:@doc).to_s).to include %(action="/foo")
end

context 'with a block' do
before :each do
expect(group).to receive(:path) { '/foo' }.with(:create, {})
expect(router).to receive(:group) { group }.with(:foo)
end

context 'with one argument' do
it 'evaluates the block in the view context and passes the data' do
block = lambda { |data| prop(:named) }
form = view_context.form(:foo)

expect(form.view).to receive(:prop)
form.create({}, &block)
end
end

context 'with more than one argument' do
it 'calls the block with the view and data' do
block = lambda { |view, data| @view, @data = view, data }
form = view_context.form(:foo)
form.create({}, &block)

expect(@view).to eq form.view
expect(@data).to eq({})
end
end
end
end

context 'when updating a form' do
it 'sets the _method and action' do
expect(request).to receive(:params) { { other: 'param' } }
expect(group).to receive(:path) { '/foo/1' }.with(:update, foo_id: 1, other: 'param')
expect(router).to receive(:group) { group }.with(:foo)

view_context.form(:foo).update(id: 1)
html = view.scope(:foo).first.instance_variable_get(:@doc).to_s
expect(html).to include %(name="_method" value="patch")
expect(html).to include %(action="/foo/1")
end
end

context 'when binding to unnamed field' do
it 'sets name attr' do
view.scope(:foo).bind(unnamed: 'test')
Expand Down

0 comments on commit c1da172

Please sign in to comment.