Conformista is a library to make building presenters -- and form objects in particular -- easier. It provides an ActiveModel-compliant base class that your own form objects can inherit from, along with standard behaviour for creating, loading, validating and persisting business objects (usually ActiveRecord models).
Conformista is distributed as a Ruby gem, which should be installed on most Macs and Linux systems. Once you have ensured you have a working installation of Ruby and Ruby gems, install the gem as follows from the command line:
$ gem install conformista
To use it with Bundler, add it to your
Then install it by running
The canonical example of a form object is a sign up form. Let's say we want to
let a visitor to our Rails application sign up for an account. That will include
class Account < ActiveRecord::Base validates :name, presence: true end class User < ActiveRecord::Base validates :email, :password, presence: true has_secure_password end class Profile < ActiveRecord::Base end
Instead of using
accepts_nested_attributes_for, or cramming all the data in
User model, or using a lot of controller logic, we use a form object to
present these three entities as a single object to the view:
class SignupController < ApplicationController def new @signup = Signup.new end def create @signup = Signup.new(params[:signup]) if @signup.save redirect_to root_url, notice: 'Thanks for signing up!' else render 'new' end end end
The single object we use is a form object that inherits from
class Signup < :: presents User => %i[email password], Account => %i[name], Profile => %i[bio twitter github] attr_accessor :password_confirmation, :terms_and_conditions validates :password, confirmation: true validates :terms_and_conditions, acceptance: true after_save :deliver_welcome_email private def deliver_welcome_email Notifications.welcome_email(user).deliver end end
We can now generate a form for our form object:
<%= form_for @signup, url: signup_path do |f| %> <p> <%= f.label :name %><br> <%= f.text_field :name %> </p> <p> <%= f.label :email %><br> <%= f.text_field :email %> </p> <p> <%= f.label :password %> <%= f.password_field :password %> </p> <p> <%= f.label :password_confirmation %><br> <%= f.password_field :password_confirmation %> </p> <p> <%= f.label :bio %><br> <%= f.text_area :bio %><br> </p> <p> <%= f.label :twitter %><br> <%= f.text_field :twitter %><br> </p> <p> <%= f.label :github %><br> <%= f.text_field :github %><br> </p> <p> <%= f.check_box :terms_and_conditions %> I have read and agree to the terms and conditions </p> <p> <%= f.submit %> </p> <% end %>
Note how the logic specifically tied to the form, like the acceptance and confirmation validations, and the email delivery, have been moved out of the model layer into the presenter layer. However, the single presenter object will re-use the data-specific validations defined in the model.
See the inline API docs for more information.
Note on Patches/Pull Requests
- Fork the project.
- Make your feature addition or bug fix.
- Add tests for it. This is important so I don't break it in a future version unintentionally.
- Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
- Send me a pull request. Bonus points for topic branches.
Please report any issues, defects or suggestions in the Github issue tracker.
What has changed?
See the HISTORY file for a detailed changelog.