Reform 0.2 Released – With has_one And has_many Support!

“Reform”: gives you a new abstraction layer for handling forms without hard-wiring them to your database. It just went 0.2 bringing you nesting to easily create forms for @has_one@ and @has_many@ relationships.

h3. Composition Forms.

In earlier versions, reform could automatically build a composition object to handle forms for multiple, unrelated objects.

class SongForm < Reform::Form
  include Reform::Form::Composition

  property :title,       on: :song
  property :written_by, on: :artist

This still works, however, the @DSL@ module got replaced by @Composition@, which you must include to make reform understand what this @on:@ option is about.
  song:   Song.find(1), 
  artist: Artist.find(2))

When creating a composite form you still need to pass in the separate objects using a hash.

h3. One-To-One Relationships.

Technically, every kind of model relations could be handled with this @Composition@ trick. Nevertheless, the new reform makes it super easy to compose forms of multiple associated models.

Say we had the following database configuration.

class Song < ActiveRecord::Base
  has_one :artist

A classic 1-to-1 association! Yay!

Although I’m using @ActiveRecord@ to demonstrate reform’s new goodies, it is important to understand that this gem *doesn’t speak a single word of @ActiveRecord@* – it uses public readers and writers, only.

To create a form to handle fields for both @Song@ and @Artist@ you can now define _nested_ forms.

class SongWithArtistForm < Reform::Form
  property :title

  property :artist do
    property :name
    property :gender

    validates :name, presence: true

See how you can now pass a block to @property@ and simply create another form class inline? Awesome, isn’t it?

(Tech note: the new inline representer feature in “representable 1.6”: made it extremely easy to implement nesting in reform).

h3. Render The Association Form.

Now, check out how this form is instantiated.

@form =

As you’re _not_ using the composition feature, all you do is pass in a single model.

song = Song.find(1)

Since you have a nested setup, this model is required to respond to @#artist@, which in turn must expose readers for @name@ and @gender@.

That should save you some work when creating the form.

Even cooler: rendering the form using Rails’ (nested) form helpers now works out-of-the-box – without inheriting all the flaws from @accepts_nested_attributes@ code.

= form_for @form do |f|
  = f.text_field :title

  = fields_for :artist do |a|
    = a.text_field :name
    = a.text_field :gender

This just works, so you don’t have to worry about rendering the proper markup – the most annoying part when writing forms in my opinion.

h3. Validating And Processing.

All you need to do now is passing the submitted data to reform.


This will run all validations from the form, even the nested one from the artist form.

Error messages – in case of bull data – can be rendered using the common steps.

- @form.errors.full_messages.each do |msg|
    = msg

Using the block-less @#save@ will push submitted and validated data to all objects automatically.

#=>       = "Beachparty"
# = "No Fun At All"

As before, you can do the saving manually: @#save@ will yield the nested input. do |data, hash|
  #=> "No Fun At All"

  #=> "No Fun At All"


Here, it’s up to you how to process the nested data. Reform just makes sure things are correctly nested.

h3. One-To-Many Relationships.

You thought that’s it? No way, we also got support for nested collections.

class Album < ActiveRecord::Base
  has_many :songs

Mapping this association in your form is pretty straight-forward.

class AlbumForm < Reform::Form
  property :name

  collection :songs do
    property :title

Creating the form works just like the @has_one@ example.

@form =
  songs: [,]

Here, it is important the @Album#songs@ returns a _collection_ of objects.

Rendering, validating and displaying errors works likewise.

You can use @fields_for@ and Rails will render the form collection. You could also go manually through the collection.

= @form.songs.each_with_index do |f, i|
  = text_field_tag "title_#{i}" ..

Currently, it’s your job to keep the number of forms visible on the page in sync with the forms created internally. That is why I pass in two new @Song@ instances to @Album@, as this will make two nested song forms appear after rendering.

If this feels inconvenient, we’re open for suggestions.

When saving sane data, you get a collection of data for the song forms. do |data, hash|
  #=> "Sanity"

  #=> "Sanity"

h3. From Here.

The new nesting feature was “requested by”: “many users”: and we’re really happy to release “this version of reform”: There will surely be issues with certain use cases and we can’t wait for your feedback!


One thought on “Reform 0.2 Released – With has_one And has_many Support!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s