mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Override default form builder for a controller
This commit is contained in:
parent
efaec3dd63
commit
2b8acdcd21
10 changed files with 129 additions and 1 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
* Add ability to override default form builder for a controller.
|
||||||
|
|
||||||
|
class AdminController < ApplicationController
|
||||||
|
default_form_builder AdminFormBuilder
|
||||||
|
end
|
||||||
|
|
||||||
|
*Kevin McPhillips*
|
||||||
|
|
||||||
* For actions with no corresponding templates, render `head :no_content`
|
* For actions with no corresponding templates, render `head :no_content`
|
||||||
instead of raising an error. This allows for slimmer API controller
|
instead of raising an error. This allows for slimmer API controller
|
||||||
methods that simply work, without needing further instructions.
|
methods that simply work, without needing further instructions.
|
||||||
|
|
|
@ -12,6 +12,7 @@ module ActionController
|
||||||
autoload :Metal
|
autoload :Metal
|
||||||
autoload :Middleware
|
autoload :Middleware
|
||||||
autoload :Renderer
|
autoload :Renderer
|
||||||
|
autoload :FormBuilder
|
||||||
|
|
||||||
autoload_under "metal" do
|
autoload_under "metal" do
|
||||||
autoload :Compatibility
|
autoload :Compatibility
|
||||||
|
|
|
@ -221,6 +221,7 @@ module ActionController
|
||||||
|
|
||||||
Cookies,
|
Cookies,
|
||||||
Flash,
|
Flash,
|
||||||
|
FormBuilder,
|
||||||
RequestForgeryProtection,
|
RequestForgeryProtection,
|
||||||
ForceSSL,
|
ForceSSL,
|
||||||
Streaming,
|
Streaming,
|
||||||
|
|
48
actionpack/lib/action_controller/form_builder.rb
Normal file
48
actionpack/lib/action_controller/form_builder.rb
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
module ActionController
|
||||||
|
# Override the default form builder for all views rendered by this
|
||||||
|
# controller and any of its descendents. Accepts a sublcass of
|
||||||
|
# +ActionView::Helpers::FormBuilder+.
|
||||||
|
#
|
||||||
|
# For example, given a form builder:
|
||||||
|
#
|
||||||
|
# class AdminFormBuilder < ActionView::Helpers::FormBuilder
|
||||||
|
# def special_field(name)
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# The controller specifies a form builder as its default:
|
||||||
|
#
|
||||||
|
# class AdminAreaController < ApplicationController
|
||||||
|
# default_form_builder AdminFormBuilder
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# Then in the view any form using +form_for+ will be an instance of the
|
||||||
|
# specified form builder:
|
||||||
|
#
|
||||||
|
# <%= form_for(@instance) do |builder| %>
|
||||||
|
# <%= builder.special_field(:name) %>
|
||||||
|
# <%= end %>
|
||||||
|
module FormBuilder
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
class_attribute :_default_form_builder, instance_accessor: false
|
||||||
|
end
|
||||||
|
|
||||||
|
module ClassMethods
|
||||||
|
# Set the form builder to be used as the default for all forms
|
||||||
|
# in the views rendered by this controller and its subclasses.
|
||||||
|
#
|
||||||
|
# ==== Parameters
|
||||||
|
# * <tt>builder</tt> - Default form builder, an instance of +ActionView::Helpers::FormBuilder+
|
||||||
|
def default_form_builder(builder)
|
||||||
|
self._default_form_builder = builder
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Default form builder for the controller
|
||||||
|
def default_form_builder
|
||||||
|
self.class._default_form_builder
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
17
actionpack/test/controller/form_builder_test.rb
Normal file
17
actionpack/test/controller/form_builder_test.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
require 'abstract_unit'
|
||||||
|
|
||||||
|
class FormBuilderController < ActionController::Base
|
||||||
|
class SpecializedFormBuilder < ActionView::Helpers::FormBuilder ; end
|
||||||
|
|
||||||
|
default_form_builder SpecializedFormBuilder
|
||||||
|
end
|
||||||
|
|
||||||
|
class ControllerFormBuilderTest < ActiveSupport::TestCase
|
||||||
|
setup do
|
||||||
|
@controller = FormBuilderController.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_default_form_builder_assigned
|
||||||
|
assert_equal FormBuilderController::SpecializedFormBuilder, @controller.default_form_builder
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,3 +1,8 @@
|
||||||
|
* Load the `default_form_builder` from the controller on initialization, which overrides
|
||||||
|
the global config if it is present.
|
||||||
|
|
||||||
|
*Kevin McPhillips*
|
||||||
|
|
||||||
* Accept lambda as `child_index` option in `fields_for` method.
|
* Accept lambda as `child_index` option in `fields_for` method.
|
||||||
|
|
||||||
*Karol Galanciak*
|
*Karol Galanciak*
|
||||||
|
|
|
@ -14,6 +14,7 @@ module ActionView
|
||||||
if @_controller = controller
|
if @_controller = controller
|
||||||
@_request = controller.request if controller.respond_to?(:request)
|
@_request = controller.request if controller.respond_to?(:request)
|
||||||
@_config = controller.config.inheritable_copy if controller.respond_to?(:config)
|
@_config = controller.config.inheritable_copy if controller.respond_to?(:config)
|
||||||
|
@_default_form_builder = controller.default_form_builder if controller.respond_to?(:default_form_builder)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,8 @@ module ActionView
|
||||||
include ModelNaming
|
include ModelNaming
|
||||||
include RecordIdentifier
|
include RecordIdentifier
|
||||||
|
|
||||||
|
attr_internal :default_form_builder
|
||||||
|
|
||||||
# Creates a form that allows the user to create or update the attributes
|
# Creates a form that allows the user to create or update the attributes
|
||||||
# of a specific model object.
|
# of a specific model object.
|
||||||
#
|
#
|
||||||
|
@ -1233,7 +1235,7 @@ module ActionView
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_form_builder_class
|
def default_form_builder_class
|
||||||
builder = ActionView::Base.default_form_builder
|
builder = default_form_builder || ActionView::Base.default_form_builder
|
||||||
builder.respond_to?(:constantize) ? builder.constantize : builder
|
builder.respond_to?(:constantize) ? builder.constantize : builder
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
21
actionview/test/template/controller_helper_test.rb
Normal file
21
actionview/test/template/controller_helper_test.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
require 'abstract_unit'
|
||||||
|
|
||||||
|
class ControllerHelperTest < ActionView::TestCase
|
||||||
|
tests ActionView::Helpers::ControllerHelper
|
||||||
|
|
||||||
|
class SpecializedFormBuilder < ActionView::Helpers::FormBuilder ; end
|
||||||
|
|
||||||
|
def test_assign_controller_sets_default_form_builder
|
||||||
|
@controller = OpenStruct.new(default_form_builder: SpecializedFormBuilder)
|
||||||
|
assign_controller(@controller)
|
||||||
|
|
||||||
|
assert_equal SpecializedFormBuilder, self.default_form_builder
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_assign_controller_skips_default_form_builder
|
||||||
|
@controller = OpenStruct.new
|
||||||
|
assign_controller(@controller)
|
||||||
|
|
||||||
|
assert_nil self.default_form_builder
|
||||||
|
end
|
||||||
|
end
|
|
@ -3269,6 +3269,30 @@ class FormHelperTest < ActionView::TestCase
|
||||||
ActionView::Base.default_form_builder = old_default_form_builder
|
ActionView::Base.default_form_builder = old_default_form_builder
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_form_builder_override
|
||||||
|
self.default_form_builder = LabelledFormBuilder
|
||||||
|
|
||||||
|
output_buffer = fields_for(:post, @post) do |f|
|
||||||
|
concat f.text_field(:title)
|
||||||
|
end
|
||||||
|
|
||||||
|
expected = "<label for='title'>Title:</label> <input name='post[title]' type='text' id='post_title' value='Hello World' /><br/>"
|
||||||
|
|
||||||
|
assert_dom_equal expected, output_buffer
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_lazy_loading_form_builder_override
|
||||||
|
self.default_form_builder = "FormHelperTest::LabelledFormBuilder"
|
||||||
|
|
||||||
|
output_buffer = fields_for(:post, @post) do |f|
|
||||||
|
concat f.text_field(:title)
|
||||||
|
end
|
||||||
|
|
||||||
|
expected = "<label for='title'>Title:</label> <input name='post[title]' type='text' id='post_title' value='Hello World' /><br/>"
|
||||||
|
|
||||||
|
assert_dom_equal expected, output_buffer
|
||||||
|
end
|
||||||
|
|
||||||
def test_fields_for_with_labelled_builder
|
def test_fields_for_with_labelled_builder
|
||||||
output_buffer = fields_for(:post, @post, builder: LabelledFormBuilder) do |f|
|
output_buffer = fields_for(:post, @post, builder: LabelledFormBuilder) do |f|
|
||||||
concat f.text_field(:title)
|
concat f.text_field(:title)
|
||||||
|
|
Loading…
Reference in a new issue