Without going to detail, I'll just show important code:
text field is passed the name of object, could be a symbol (:user) or string ("user"). method is datbase attribute or virtual attribute. the options hash, among other things, includes the object if persisted (e.g. @user). def text_field(object_name, method, options = {}) Tags::TextField.new(object_name, method, self, options).render end
TextField doesn't have initialize, it calls on super which is Base, and we create some instance variables holding our object information and so forth: class Base ...
def initialize(object_name, method_name, template_object, options = {}) @object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup @template_object = template_object
@object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\] $/,"]") @object = retrieve_object(options.delete(:object)) @options = options ...
We call render on text field object def render options = @options.stringify_keys options["size"] = options["maxlength"] unless options.key? ("size") options["type"] ||= field_type options["value"] = options.fetch("value") { value_before_type_cast(object) } unless field_type == "file" options["value"] &&= ERB::Util.html_escape(options["value"]) add_default_name_and_id(options) tag("input", options) end
def tag(name, options = nil, open = false, escape = true) "<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe end
and thats pretty much it. Wheres the name attribute and its value appended to the returned string from render?