Upload
szymon-fiedler
View
473
Download
2
Embed Size (px)
Citation preview
Form objectsdone right
/ / Szymon Fiedler @fidelski @arkency
Form #1 Class Signup include ActiveModel::Model attr_reader :company, :user
attr_accessor( :name, :company_name, :email ) validates :company_name, presence: true validates :email, presence: true, email: true validates :name, presence: true validate :email_uniquenes def save if valid? persist! true else false end end
def persisted? false end private
def email_uniqueness errors.add(:email, "Email already used dude") if User.where(email: email).exists? end def persist!
Form #2 class Signup include Virtus.model extend ActiveModel::Naming include ActiveModel::Conversion include ActiveModel::Validations attr_reader :user attr_reader :company attribute :name, String attribute :company_name, String attribute :email, String validates :company_name, presence: true validates :email, presence: true, email: true validates :name, presence: true validate :email_uniquenes def persisted? false end def save if valid? persist! true else false end end private def email_uniqueness errors.add(:email, "Email already used dude") if User.where(email: email).exists?
What's wrong with theseexamples?
Is the persistence aresponsibility of the form object?Nope, it is not
Form #3 class Signup ValidationError = Class.new(StandardError) include Virtus.model include ActiveModel::Validations attribute :name, String attribute :company_name, String attribute :email, String validates :company_name, presence: true validates :email, presence: true, email: true validates :name, presence: true def persisted? false end
def validate! raise ValidationError, errors unless valid? end end
Let's use service class SignupService
def call(form_object) form_object.validate!
if User.where(email: form_object.email).exists? form_object.errors.add(:email, "email already taken") end company = Company.create!(name: company_name) User.create!(name: form_object.name, email: form_object.email, company: company)
form_object rescue from_object.class::ValidationError form_object # we have errors here rescue ActiveRecord::RecordInvalid => e # add additional errors to form object end end
Controller class FancyController < ApplicationController def new @signup = Signup.new end def create form = Signup.new(params[:signup]) @signup = SignupService.new.call(form) end end
hawkins.io
Thanks