Skip to content

Instantly share code, notes, and snippets.

@mtrpcic
Last active August 29, 2015 13:57
Show Gist options
  • Save mtrpcic/9743490 to your computer and use it in GitHub Desktop.
Save mtrpcic/9743490 to your computer and use it in GitHub Desktop.
# I'm trying to convert a form I'm using over to use "Form Objects". I created a base
# object that all my forms can inherit from:
class FormObject
include Virtus.model
extend ActiveModel::Naming
include ActiveModel::Validations
include ActiveModel::Conversion
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
# Forms are never themselves persisted
def persisted?
false
end
def save
if valid?
persist!
else
false
end
end
end
# Then, I created a custom form. This form is for a user/site combination. When a user
# registers an account, we also create a Site for them.
class NewUserForm < FormObject
#attr_reader :user
#attr_reader :company
# User Attributes
attribute :email, String
attribute :password, String
attribute :password_confirmation, String
# Site Attributes
attribute :title, String
attribute :slug, String
attribute :tagline, String
# User Validations
validates :email, :presence => true
validates :password, :presence => true
validates :password_confirmation, :presence => true
# Site Validations
validates :slug, :presence => true
def persist!
@user = User.create!(:email => email, :password => password, :password_confirmation => password_confirmation)
@site = Site.create!(:slug => slug, :title => title, :tagline => tagline)
end
end
# Questions
#
# 1. The validations on the FormObject can't do Unique tests. For example, the user.email needs
# to be globally unique, but that validation needs to be on the model for it to work. Because
# of this, my FormObject might appear valid, but the persist! method will fail because of an
# invalid user.
#
# 2. I want my user experience to be good, so if there is an invalid form, the server re-renders
# the `new` action with a populated form, so the user doesn't have to fill it out again. The
# problem is if I do "form_for(@form_object_instance)", I get errors about an "implicit cast
# from String to Integer". If I change it to "form_for('signup')", it works.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment