Skip to content

Instantly share code, notes, and snippets.

@skmetz
Created June 17, 2009 13:35
Show Gist options
  • Save skmetz/131233 to your computer and use it in GitHub Desktop.
Save skmetz/131233 to your computer and use it in GitHub Desktop.
remove case statement from form_for, etc
From 164f12ca299a407d9d31f32e400daaef12ab736a Mon Sep 17 00:00:00 2001
From: Sandi Metz <skmetz@gmail.com>
Date: Mon, 15 Jun 2009 08:01:48 -0400
Subject: [PATCH] remove case statements, use double dispatch
---
actionpack/lib/action_view/helpers.rb | 2 +
actionpack/lib/action_view/helpers/form_helper.rb | 43 ++++++--------
.../helpers/form_helper_core_extensions.rb | 59 ++++++++++++++++++++
.../lib/action_view/helpers/prototype_helper.rb | 19 +------
4 files changed, 81 insertions(+), 42 deletions(-)
create mode 100644 actionpack/lib/action_view/helpers/form_helper_core_extensions.rb
diff --git a/actionpack/lib/action_view/helpers.rb b/actionpack/lib/action_view/helpers.rb
index 693ab7c..35259c5 100644
--- a/actionpack/lib/action_view/helpers.rb
+++ b/actionpack/lib/action_view/helpers.rb
@@ -1,3 +1,5 @@
+require 'action_view/helpers/form_helper_core_extensions'
+
module ActionView #:nodoc:
module Helpers #:nodoc:
autoload :ActiveRecordHelper, 'action_view/helpers/active_record_helper'
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index a85751c..620dd22 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -232,30 +232,29 @@ module ActionView
def form_for(record_or_name_or_array, *args, &proc)
raise ArgumentError, "Missing block" unless block_given?
+ object, object_name, options = standardize_form_invocation!(record_or_name_or_array, args)
+
+ concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {}))
+ fields_for(object_name, *(args << options), &proc)
+ concat('</form>')
+ end
+
+ def standardize_form_invocation!(record_or_name_or_array, args)
options = args.extract_options!
- case record_or_name_or_array
- when String, Symbol
- object_name = record_or_name_or_array
- when Array
- object = record_or_name_or_array.last
- object_name = ActionController::RecordIdentifier.singular_class_name(object)
- apply_form_for_options!(record_or_name_or_array, options)
- args.unshift object
- else
- object = record_or_name_or_array
- object_name = ActionController::RecordIdentifier.singular_class_name(object)
- apply_form_for_options!([object], options)
+ object = record_or_name_or_array.as_form_object
+ object_name = object.form_object_name
+
+ if object.acts_like_model?
+ apply_form_for_options!(record_or_name_or_array.as_array, options)
args.unshift object
end
-
- concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {}))
- fields_for(object_name, *(args << options), &proc)
- concat('</form>')
+
+ [object, object_name, options]
end
def apply_form_for_options!(object_or_array, options) #:nodoc:
- object = object_or_array.is_a?(Array) ? object_or_array.last : object_or_array
+ object = object_or_array.as_form_object
html_options =
if object.respond_to?(:new_record?) && object.new_record?
@@ -300,14 +299,8 @@ module ActionView
raise ArgumentError, "Missing block" unless block_given?
options = args.extract_options!
- case record_or_name_or_array
- when String, Symbol
- object_name = record_or_name_or_array
- object = args.first
- else
- object = record_or_name_or_array
- object_name = ActionController::RecordIdentifier.singular_class_name(object)
- end
+ object = record_or_name_or_array.as_fields_for_form_object(args)
+ object_name = record_or_name_or_array.form_object_name
builder = options[:builder] || ActionView::Base.default_form_builder
yield builder.new(object_name, object, self, options, block)
diff --git a/actionpack/lib/action_view/helpers/form_helper_core_extensions.rb b/actionpack/lib/action_view/helpers/form_helper_core_extensions.rb
new file mode 100644
index 0000000..8d6e924
--- /dev/null
+++ b/actionpack/lib/action_view/helpers/form_helper_core_extensions.rb
@@ -0,0 +1,59 @@
+class String
+ def form_object_name
+ self
+ end
+
+ def as_fields_for_form_object(args)
+ args.first
+ end
+
+ def acts_like_model?
+ false
+ end
+end
+
+class Symbol
+ def form_object_name
+ self
+ end
+
+ def as_fields_for_form_object(args)
+ args.first
+ end
+
+ def acts_like_model?
+ false
+ end
+end
+
+class Array
+ def as_form_object
+ last
+ end
+
+ def as_array
+ self
+ end
+end
+
+class Object
+ def as_form_object
+ self
+ end
+
+ def as_fields_for_form_object(args)
+ as_form_object
+ end
+
+ def form_object_name
+ ActionController::RecordIdentifier.singular_class_name(self)
+ end
+
+ def as_array
+ [self]
+ end
+
+ def acts_like_model?
+ true
+ end
+end
\ No newline at end of file
diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb
index 99676a9..edebf49 100644
--- a/actionpack/lib/action_view/helpers/prototype_helper.rb
+++ b/actionpack/lib/action_view/helpers/prototype_helper.rb
@@ -374,23 +374,8 @@ module ActionView
#
# See FormHelper#form_for for additional semantics.
def remote_form_for(record_or_name_or_array, *args, &proc)
- options = args.extract_options!
-
- case record_or_name_or_array
- when String, Symbol
- object_name = record_or_name_or_array
- when Array
- object = record_or_name_or_array.last
- object_name = ActionController::RecordIdentifier.singular_class_name(object)
- apply_form_for_options!(record_or_name_or_array, options)
- args.unshift object
- else
- object = record_or_name_or_array
- object_name = ActionController::RecordIdentifier.singular_class_name(record_or_name_or_array)
- apply_form_for_options!(object, options)
- args.unshift object
- end
-
+ object, object_name, options = standardize_form_invocation!(record_or_name_or_array, args)
+
concat(form_remote_tag(options))
fields_for(object_name, *(args << options), &proc)
concat('</form>')
--
1.6.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment