Class: HumpyardForm::FormBuilder
- Inherits:
-
ActionView::Helpers::FormBuilder
- Object
- ActionView::Helpers::FormBuilder
- HumpyardForm::FormBuilder
- Defined in:
- lib/humpyard_form/form_builder.rb
Overview
HumpyardForm::FormHelper is a helper for forms
Constant Summary collapse
- @@file_methods =
[ :file?, :public_filename ]
Instance Attribute Summary collapse
-
#form_type ⇒ Object
readonly
Returns the value of attribute form_type.
-
#html_options ⇒ Object
readonly
Returns the value of attribute html_options.
-
#object ⇒ Object
readonly
Returns the value of attribute object.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#url ⇒ Object
readonly
Returns the value of attribute url.
Instance Method Summary collapse
-
#column_info(method) ⇒ Object
Get Column infomation for methods.
-
#create_boolean_collection(options) ⇒ Object
Returns a hash to be used by radio and select inputs when a boolean field is provided.
-
#default_input_type(method) ⇒ Object
For methods that have a database column, take a best guess as to what the input method should be.
-
#detect_group_association(method, group_by) ⇒ Object
Detects the method to call for fetching group members from the groups when grouping select options.
-
#detect_label_and_value_method!(collection_or_instance, options = {}) ⇒ Object
Detects the label and value methods from a collection values set in @@collection_label_methods.
-
#detect_label_method(collection) ⇒ Object
Detected the label collection method when none is supplied using the values set in @@collection_label_methods.
-
#find_collection_for_column(column, options) ⇒ Object
Used by select and radio inputs.
-
#find_raw_collection_for_column(column, options) ⇒ Object
As #find_collection_for_column but returns the collection without mapping the label and value.
-
#initialize(renderer, object, options = {}) ⇒ FormBuilder
constructor
A new instance of FormBuilder.
-
#input(method, options = {}) ⇒ Object
:nodoc:.
- #inputs ⇒ Object
- #namespace ⇒ Object
-
#reflection_for(method) ⇒ Object
If an association method is passed in (f.input :author) try to find the reflection object.
- #send_or_call(duck, object) ⇒ Object
- #submit(options = {}) ⇒ Object
-
#translation_info(method) ⇒ Object
:nodoc:.
- #uuid ⇒ Object
Constructor Details
#initialize(renderer, object, options = {}) ⇒ FormBuilder
Returns a new instance of FormBuilder.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/humpyard_form/form_builder.rb', line 11 def initialize(renderer, object, ={}) @renderer = renderer @object = @renderer.convert_to_model(object) @html_options = .delete(:html) || {} @url = .delete(:url) || @renderer.polymorphic_path(@object) @options = if object.respond_to?(:persisted?) && object.persisted? @form_type = 'Edit' @html_options[:'data-action'] = @renderer.dom_class(object, :edit), @html_options[:method] = :put else @form_type = 'New' @html_options[:'data-action'] = @renderer.dom_class(object, :new), @html_options[:method] = :post end end |
Instance Attribute Details
#form_type ⇒ Object (readonly)
Returns the value of attribute form_type.
5 6 7 |
# File 'lib/humpyard_form/form_builder.rb', line 5 def form_type @form_type end |
#html_options ⇒ Object (readonly)
Returns the value of attribute html_options.
5 6 7 |
# File 'lib/humpyard_form/form_builder.rb', line 5 def @html_options end |
#object ⇒ Object (readonly)
Returns the value of attribute object.
5 6 7 |
# File 'lib/humpyard_form/form_builder.rb', line 5 def object @object end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
5 6 7 |
# File 'lib/humpyard_form/form_builder.rb', line 5 def @options end |
#url ⇒ Object (readonly)
Returns the value of attribute url.
5 6 7 |
# File 'lib/humpyard_form/form_builder.rb', line 5 def url @url end |
Instance Method Details
#column_info(method) ⇒ Object
Get Column infomation for methods
69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/humpyard_form/form_builder.rb', line 69 def column_info(method) column = @object.column_for_attribute(method) if @object.respond_to?(:column_for_attribute) # translated attributes dont have a column info at this point # check the associated translation class if not column tx_info = translation_info(method) if tx_info column = tx_info[:column] end end column end |
#create_boolean_collection(options) ⇒ Object
Returns a hash to be used by radio and select inputs when a boolean field is provided.
232 233 234 235 236 237 238 |
# File 'lib/humpyard_form/form_builder.rb', line 232 def create_boolean_collection() #:nodoc: [:true] ||= ::I18n.t(:yes) [:false] ||= ::I18n.t(:no) [:value_as_class] = true unless .key?(:value_as_class) [ [ .delete(:true), true], [ .delete(:false), false ] ] end |
#default_input_type(method) ⇒ Object
For methods that have a database column, take a best guess as to what the input method should be. In most cases, it will just return the column type (eg :string), but for special cases it will simplify (like the case of :integer, :float & :decimal to :numeric), or do something different (like :password and :select).
If there is no column for the method (eg “virtual columns” with an attr_accessor), the default is a :string, a similar behaviour to Rails’ scaffolding.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/humpyard_form/form_builder.rb', line 92 def default_input_type(method) #:nodoc: column = column_info(method) if column # handle the special cases where the column type doesn't map to an input method return :time_zone if column.type == :string && method.to_s =~ /time_zone/ return :select if column.type == :integer && method.to_s =~ /_id$/ return :datetime if column.type == :timestamp return :numeric if [:integer, :float, :decimal].include?(column.type) return :password if column.type == :string && method.to_s =~ /password/ #return :country if column.type == :string && method.to_s =~ /country/ # otherwise assume the input name will be the same as the column type (eg string_input) return column.type else if @object #return :select if find_reflection(method) file = @object.send(method) if @object.respond_to?(method) if file && @@file_methods.any? { |m| file.respond_to?(m) } if file.styles.keys.empty? return :file else return :image_file end end end return :password if method.to_s =~ /password/ return :string end end |
#detect_group_association(method, group_by) ⇒ Object
Detects the method to call for fetching group members from the groups when grouping select options
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/humpyard_form/form_builder.rb', line 187 def detect_group_association(method, group_by) object_to_method_reflection = self.reflection_for(method) method_class = object_to_method_reflection.klass method_to_group_association = method_class.reflect_on_association(group_by) group_class = method_to_group_association.klass # This will return in the normal case return method.to_s.pluralize.to_sym if group_class.reflect_on_association(method.to_s.pluralize) # This is for belongs_to associations named differently than their class # form.input :parent, :group_by => :customer # eg. # class Project # belongs_to :parent, :class_name => 'Project', :foreign_key => 'parent_id' # belongs_to :customer # end # class Customer # has_many :projects # end group_method = method_class.to_s.underscore.pluralize.to_sym return group_method if group_class.reflect_on_association(group_method) # :projects # This is for has_many associations named differently than their class # eg. # class Project # belongs_to :parent, :class_name => 'Project', :foreign_key => 'parent_id' # belongs_to :customer # end # class Customer # has_many :tasks, :class_name => 'Project', :foreign_key => 'customer_id' # end possible_associations = group_class.reflect_on_all_associations(:has_many).find_all{|assoc| assoc.klass == object_class} return possible_associations.first.name.to_sym if possible_associations.count == 1 raise "Cannot infer group association for #{method} grouped by #{group_by}, there were #{possible_associations.empty? ? 'no' : possible_associations.size} possible associations. Please specify using :group_association" end |
#detect_label_and_value_method!(collection_or_instance, options = {}) ⇒ Object
Detects the label and value methods from a collection values set in @@collection_label_methods. It will use and delete the options :label_method and :value_methods when present
172 173 174 175 176 |
# File 'lib/humpyard_form/form_builder.rb', line 172 def detect_label_and_value_method!(collection_or_instance, = {}) #:nodoc label = .delete(:label_method) || detect_label_method(collection_or_instance) value = .delete(:value_method) || :id [label, value] end |
#detect_label_method(collection) ⇒ Object
Detected the label collection method when none is supplied using the values set in @@collection_label_methods.
181 182 183 |
# File 'lib/humpyard_form/form_builder.rb', line 181 def detect_label_method(collection) #:nodoc: HumpyardForm::config.collection_label_methods.detect { |m| collection.first.respond_to?(m) } end |
#find_collection_for_column(column, options) ⇒ Object
Used by select and radio inputs. The collection can be retrieved by three ways:
-
Explicitly provided through :collection
-
Retrivied through an association
-
Or a boolean column, which will generate a localized { “Yes” => true, “No” => false } hash.
If the collection is not a hash or an array of strings, fixnums or arrays, we use label_method and value_method to retreive an array with the appropriate label and value.
136 137 138 139 140 141 142 143 144 145 |
# File 'lib/humpyard_form/form_builder.rb', line 136 def find_collection_for_column(column, ) #:nodoc: collection = find_raw_collection_for_column(column, ) # Return if we have an Array of strings, fixnums or arrays return collection if (collection.instance_of?(Array) || collection.instance_of?(Range)) && [Array, Fixnum, String, Symbol].include?(collection.first.class) label, value = detect_label_and_value_method!(collection, ) collection.map { |o| [send_or_call(label, o), send_or_call(value, o)] } end |
#find_raw_collection_for_column(column, options) ⇒ Object
As #find_collection_for_column but returns the collection without mapping the label and value
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/humpyard_form/form_builder.rb', line 149 def find_raw_collection_for_column(column, ) #:nodoc: collection = if [:collection] .delete(:collection) elsif reflection = self.reflection_for(column.to_s.gsub(/_id$/, '').to_sym) [:find_options] ||= {} if conditions = reflection.[:conditions] [:find_options][:conditions] = reflection.klass.merge_conditions(conditions, [:find_options][:conditions]) end reflection.klass.find(:all, [:find_options]) else create_boolean_collection() end collection = collection.to_a if collection.is_a?(Hash) collection end |
#input(method, options = {}) ⇒ Object
:nodoc:
44 45 46 47 48 |
# File 'lib/humpyard_form/form_builder.rb', line 44 def input(method, ={}) #:nodoc: [:as] ||= default_input_type(method) [:translation_info] = translation_info(method) @renderer.render :partial => "/humpyard_form/form_element", :locals => {:form => self, :name => method, :options => , :as => [:as]} end |
#inputs ⇒ Object
41 42 |
# File 'lib/humpyard_form/form_builder.rb', line 41 def inputs end |
#namespace ⇒ Object
29 30 31 32 33 34 35 |
# File 'lib/humpyard_form/form_builder.rb', line 29 def namespace if @options[:as] @options[:as] else @object.class.name.underscore.gsub('/', '_') end end |
#reflection_for(method) ⇒ Object
If an association method is passed in (f.input :author) try to find the reflection object.
244 245 246 |
# File 'lib/humpyard_form/form_builder.rb', line 244 def reflection_for(method) #:nodoc: @object.class.reflect_on_association(method) if @object.class.respond_to?(:reflect_on_association) end |
#send_or_call(duck, object) ⇒ Object
248 249 250 251 252 253 254 |
# File 'lib/humpyard_form/form_builder.rb', line 248 def send_or_call(duck, object) if duck.is_a?(Proc) duck.call(object) else object.send(duck) end end |
#submit(options = {}) ⇒ Object
50 51 52 |
# File 'lib/humpyard_form/form_builder.rb', line 50 def submit(={}) @renderer.render :partial => '/humpyard_form/submit', :locals => {:form => self, :options => } end |
#translation_info(method) ⇒ Object
:nodoc:
54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/humpyard_form/form_builder.rb', line 54 def translation_info(method) #:nodoc: if @object.respond_to?(:translated_attribute_names) and @object.translated_attribute_names.include?(method) tmp = @object.class.translation_class.new if tmp column = tmp.column_for_attribute(method) if tmp.respond_to?(:column_for_attribute) if column {:locales => HumpyardForm::config.locales, :column => column} end end else false end end |
#uuid ⇒ Object
37 38 39 |
# File 'lib/humpyard_form/form_builder.rb', line 37 def uuid @uuid ||= rand(1000) end |