Skip to content

Instantly share code, notes, and snippets.

@RichardJordan
Last active August 29, 2015 13:56
Show Gist options
  • Save RichardJordan/9059862 to your computer and use it in GitHub Desktop.
Save RichardJordan/9059862 to your computer and use it in GitHub Desktop.
Registration of user and account: Registration form object
# see https://gist.github.com/RichardJordan/9059633 for explanation
# -----------------------------------------------------------------
class Registration
extend ActiveModel::Naming
include ActiveModel::Model
include ActiveModel::Validations::Callbacks
include ActiveModel::ForbiddenAttributesProtection
attr_accessor :email, :password, :password_confirmation,
:shortname, :fullname
attr_reader :saved
attr_writer :account_source, :user_source
delegate :email=, :password=, :password_confirmation=,
:email, :password, :password_confirmation, to: :user
delegate :shortname=, :fullname=,
:shortname, :fullname, to: :account
before_validation :downcase_email_and_shortname
validates :email, presence: true, email_format: true
validates :password_confirmation, presence: true
validates :password,
presence: true,
length: {
minimum: 6,
allow_blank: false,
message: "must be at least 6 characters"
}
validates :fullname, length: { maximum: 250 }
validates :shortname,
presence: true,
length: { minimum: 5, maximum: 50,
message: "Short name must be 5-50 characters long" },
format: /\A[A-Za-z0-9_-]+\Z/
validate :verify_unique_email
validate :verify_unique_shortname
def account
@account ||= account_source.call
end
def attributes
{ email: email, password: password,
password_confirmation: password_confirmation,
fullname: fullname, shortname: shortname }
end
def attributes=(attrs)
sanitize_for_mass_assignment(attrs).each { |k,v| send("#{k}=", v) }
end
def new_record?
!saved
end
def persisted?
false
end
def save!
@saved = account.save! && user.save!
end
def user
@user ||= user_source.call
end
private
def account_source
@account_source ||= Account.public_method(:new)
end
def downcase_email_and_shortname
email.downcase! if email
shortname.downcase! if shortname
end
def user_source
@user_source ||= User.public_method(:new)
end
def verify_unique_email
if email && (User.exists? email: email)
errors.add :email, "has already been signed up"
end
end
def verify_unique_shortname
if shortname && (Account.exists? shortname: shortname)
errors.add :shortname, "has already been taken"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment