ActiveModel Form Objects
Submitting form data is a common feature of web applications -- allowing users to submit their information and giving them feedback whether the information is valid or not. [ActiveRecord](http://api.rubyonrails.org/classes/ActiveRecord/Base.html) comes with a powerful set of validators for attributes on a persisted data model. When data is not persisted, or used for other non-active record purposes, [Active Model Helper Modules](http://api.rubyonrails.org/classes/ActiveModel.html) reduce the complexity of validations on your plain old Ruby objects. ## Routing Create the routes needed for displaying the form object and posting the data + Restrict resources to the routes you need using `only:`
# config/routes.rb resources :registration, only: [:new, :create]
## Controller and Actions Create a controller with `new` and `create` actions. + `respond_with` will re-render the `new` action if there are any validation errors on the model + If there are no errors on the model the visitor will be redirected to `show` the current resource. In this case the user will be redirected to `some_other_success_path`
# app/controllers/registration_controller.rb class RegistrationsController < ApplicationController respond_to :html def new @registration = Registration.new end def create @registration = Registration.new(registration_params) @registration.register respond_with @registration, location: some_success_path end private def registration_params # ... end end
## View with Registration Form The view renders a web form with fields to submit. + Use the ActiveModel object `@registration` in the form + Form generates the endpoint `registration_path` and method of delivery `post` + Validation errors will display inline within the form just like ActiveRecord
# app/views/registration/new.html.erb <%= form_for @registration do |f| %> <%= f.label :first_name, 'First Name' %>: <%= f.text_field :first_name %> … <%= f.submit %> <% end %>
## Object with ActiveModel Conversion, Naming, and Validations Use any of the [ActiveRecord Validations](http://guides.rubyonrails.org/active_record_validations_callbacks.html) in the model. + Command pattern used when calling `register` method. + ActiveRecord validation syntax on attributes. + ActiveModel::Model mixin includes modules, and includes an initialization method.
# app/models/registration.rb class Registration include ActiveModel::Model attr_accessor( :company_name, :email, :first_name, :last_name, :terms_of_service ) validates :company_name, presence: true validates :email, presence: true, email: true validates :first_name, presence: true validates :last_name, presence: true validates :terms_of_service, acceptance: true def register if valid? # Do something interesting here # - create user # - send notifications # - log events, etc. end end private def create_user # ... end end
### Takeaways + Keep business logic out of the Controller and Views + Add validation support to plain Ruby object using ActiveModel includes + Display data validation errors in the form + Use ActiveModel naming conventions for generating form endpoints
Written by Harlow Ward










