Skip to content

Instantly share code, notes, and snippets.

@aganov
Last active October 18, 2019 11:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aganov/8044b18ed37825f5332dc7587a02c565 to your computer and use it in GitHub Desktop.
Save aganov/8044b18ed37825f5332dc7587a02c565 to your computer and use it in GitHub Desktop.
poor man's reform
class ApplicationForm
include ActiveAttr::Model
attr_reader :model
delegate :new_record?, :persisted?, :model_name, :id, to: :model
class << self
# Don't sync virtual attributes to model
# ex: attribute :accept_tos, virtual: true
def virtual_attribute_names
attributes.select do |name, attribute|
attribute[:virtual]
end.keys
end
def model_attribute_names
attribute_names - virtual_attribute_names
end
end
def initialize(model)
raise ArgumentError, "model can't be blank" if model.blank?
@model = model
prepopulate
end
def validate(params)
params.each do |name, value|
send "#{name}=", value if self.class.attribute_names.include?(name.to_s)
end
valid?
end
def save_model
model.save
end
def save
sync_model
save_model
end
private
def prepopulate
self.class.model_attribute_names.each do |name|
send "#{name}=", model.send(name)
end
end
def sync_model
self.class.model_attribute_names.each do |name|
model.send "#{name}=", send(name)
end
end
end
class UserBan < ApplicationRecord
belongs_to :user
end
class UserBanForm < ApplicationForm
attribute :reason
attribute :confirm, type: Boolean, virtual: true
validate :reason, presence: true
def save_model
model.save!
UserMailer.banned(model.user).deliver_later
end
end
class UserBansController < ApplicationController
def create
@form = UserBanForm.new(current_user.ban || current_user.build_ban)
if @form.validate(params.permit(:user_ban))
@form.save
redirect_back notice: "Horray!"
else
render "new"
end
end
end
class UserForm < ApplicationForm
attribute :name
attribute :accept_tos, virtual: true
validates :name, presence: true
validates :accept_tos, acceptance: true
def save_model
model.save do
UserMailer.welcome.deliver_later
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment