module Puffer class Field attr_accessor :resource, :field_name, :field_set, :options, :children def initialize field_name, resource, *fieldset_and_options, &block @field_name = field_name.to_s @resource = resource @options = fieldset_and_options.extract_options! @field_set = fieldset_and_options.first @children = Puffer::FieldSet.new swallow_nil{field_set.name} block.bind(self).call if block end def field name, options = {}, &block @children.field(name, swallow_nil{reflection.klass}, options, &block) end def native? model == resource end def to_s field_name end def name @name ||= field_name.split('.').last end def path @path ||= field_name.split('.')[0..-2].join('.') end def human @human ||= model && model.human_attribute_name(name) end def order @order ||= options[:order] || query_column end def type @type ||= options[:type] || custom_type || column_type || :string end def custom_type return :select if options.key?(:select) return :password if name =~ /password/ return reflection.macro if reflection end def reflection @reflection ||= model && model.reflect_on_association(name.to_sym) end def input_options options[:html] || {} end def component_class @component_class ||= Puffer::Component.component_for type end def component @component ||= component_class.new self end def render controller, context, *args component.process controller, context, *args end def model @model ||= begin associations = field_name.split('.') associations.pop temp = resource while temp.reflect_on_association(association = swallow_nil{associations.shift.to_sym}) do temp = temp.reflect_on_association(association).klass end temp end if resource end def column @column ||= model && model.to_adapter.columns_hash[name] end def column_type column[:type] if column end def query_column "#{model.table_name}.#{name}" if column end end end