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`
|
||||
instead of raising an error. This allows for slimmer API controller
|
||||
methods that simply work, without needing further instructions.
|
||||
|
|
|
@ -12,6 +12,7 @@ module ActionController
|
|||
autoload :Metal
|
||||
autoload :Middleware
|
||||
autoload :Renderer
|
||||
autoload :FormBuilder
|
||||
|
||||
autoload_under "metal" do
|
||||
autoload :Compatibility
|
||||
|
|
|
@ -221,6 +221,7 @@ module ActionController
|
|||
|
||||
Cookies,
|
||||
Flash,
|
||||
FormBuilder,
|
||||
RequestForgeryProtection,
|
||||
ForceSSL,
|
||||
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.
|
||||
|
||||
*Karol Galanciak*
|
||||
|
|
|
@ -14,6 +14,7 @@ module ActionView
|
|||
if @_controller = controller
|
||||
@_request = controller.request if controller.respond_to?(:request)
|
||||
@_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
|
||||
|
||||
|
|
|
@ -114,6 +114,8 @@ module ActionView
|
|||
include ModelNaming
|
||||
include RecordIdentifier
|
||||
|
||||
attr_internal :default_form_builder
|
||||
|
||||
# Creates a form that allows the user to create or update the attributes
|
||||
# of a specific model object.
|
||||
#
|
||||
|
@ -1233,7 +1235,7 @@ module ActionView
|
|||
end
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
output_buffer = fields_for(:post, @post, builder: LabelledFormBuilder) do |f|
|
||||
concat f.text_field(:title)
|
||||
|
|
Loading…
Reference in a new issue