public
Description:
Home | Edit | New

Subform Form Overrides

If you want to customize the form interface for a column in a subform you have two choices: You can define a specially named partial, or you can define a specially named method in your helper file. The difference between the partial and the helper method is that the partial will be responsible for displaying the label and everything, whereas the helper will only be responsible for displaying the input element (or other interface).

These overrides can be used to hide fields on the subform, or even to replace standard inputs with javascript-enabled inputs.

These overrides are currently used by Create and Update.

Overriding the form interface for a subform column follows the same process as for a normal form (See Form Overrides for more details.) There are a few minor differences however that you need to be aware of.

Subform Helper Override

The following differences exist between overriding the form interface helper for a subform column that for a normal form column:

  1. The helper method for your column form override must be placed in the helper file for the controller that calls the subform. E.g. If you have a controller called User, and it calls the controller ContactInformation (because User has an association to ContactInformation), then if you want to override the form interface used by a column in the ContactInformation subform you must place your form override method it in the UserHelper and not in the ContactInformationHelper.
  2. You must use the input_name parameter to set the NAME and ID form parameters, otherwise ActiveScaffold will not be able to save the data from your overridden column correctly.

Below is an example of overriding the state_id column in the ContactInformation subform that is called via the User controller. In this case we want to display a list of names of States, instead of their IDs.

First you setup your classes and their columns (only the columns from ContactInformation are show below):

class User < ActiveRecord::Base
  belongs_to :contact_information
end

class ContactInformation < ActiveRecord::Base
  has_many :users
  belongs_to :state
end

class State < ActiveRecord::Base
  has_many :contact_informations
end

class CreateContactInformations < ActiveRecord::Migration
  def self.up
    create_table :contact_informations do |t|
      t.column :address, :string
      t.column :city, :string
      t.column :state_id, :integer
    end
  end

  def self.down
    drop_table :contact_informations
  end
end

Then you setup your column form interface override in your UserHelper file. This override will create a list of all States in the system and display their names, instead of just showing their IDs:

module UserHelper

  def state_id_form_column(record, input_name)
    collection_select(:record, :state_id, State.find(:all, :order => "name"), :id, :name, {}, {:name => input_name} )
  end

end

Notice the use of input_name in the code above. This is used to set the name of the column correctly in your form element to be record[association_name][column_name]. Without this the NAME and ID for your column would be set to the current context, and that would of course belong to User (E.g. record[column_name]). In such a case ActiveScaffold would try to save the state_id form element data to User, and this would fail because state_id belongs to ContactInformation.

Subform Partial Override (overriding the form element and the label)

The partial override is responsible for displaying the field label, element, description, etc.. It should be named _#{column_name}_form_column.rhtml and be placed in the views folder belonging to the controller that called the subform. E.g. In the example above you would place your overriden form partial in app/views/user/ and not in app/views/contact_information/. In this partial you can put all the custom code you want to use to display the form input element for this column.

Last edited by scambra, Wed Sep 23 07:09:21 -0700 2009
Home | Edit | New
Versions: