Skip to content

Instantly share code, notes, and snippets.

@mrboli
Last active March 9, 2016 21:36
Show Gist options
  • Save mrboli/8883d67efb62074a35db to your computer and use it in GitHub Desktop.
Save mrboli/8883d67efb62074a35db to your computer and use it in GitHub Desktop.
class Business < ActiveRecord::Base
include SubuserExtender
# ...
end
class Lender < ActiveRecord::Base
include SubuserExtender
# ...
end
module UserAccessorMethods
def define_user_accessors
all_attributes = User.content_columns.map(&:name) + [:skip_confirmation]
# Prevent delegating duplicate fields to user, also check if the database hasn't been migrated yet and if the columsn don't exist
class_attributes = self.table_exists? ? self.content_columns.map(&:name) : []
ignored_attributes = class_attributes + ["created_at", "updated_at"]
attributes_to_delegate = all_attributes - ignored_attributes
attributes_to_delegate.each do |attr|
class_eval <<-RUBY
def #{attr}
user.#{attr}
end
def #{attr}=(value)
self.user.#{attr} = value
end
def #{attr}?
self.user.#{attr}?
end
RUBY
end
end
end
require 'mti_accessors.rb'
module SubuserExtender
include UserAccessorMethods
def self.included(base)
# Sub-User Associations
base.belongs_to :user
base.validate :user_must_be_valid
base.alias_method_chain :user, :autobuild
# Delegate User Methods / Properties
base.extend UserAccessorMethods
base.define_user_accessors
# Callbacks / Special Options
base.before_create :generate_uuid
base.before_save :save_user
base.devise :registerable
end
def save_user
# On a recursive save, carry over the user errors
if !user.save
add_user_errors
end
end
def user_with_autobuild
user_without_autobuild || build_user
end
def method_missing(meth, *args, &blk)
# Check if the model has the current method
super
rescue NoMethodError
p '!subuser_extender: nomethod Error'
# If the model doesn't have the method, delegate if it
# isn't arleady delegated from another MTI call
if !errors[:user_mti_method_missing].any?
errors.add(:user_mti_method_missing, 'no method')
user.send(meth, *args, &blk)
else
raise NoMethodError
end
end
protected
def add_user_errors
user.errors.each do |attr, message|
errors.add(attr, message)
end
end
# Enforce Validation
def user_must_be_valid
unless user.valid?
add_user_errors
end
end
end
class User < ActiveRecord::Base
has_many :businesses, :autosave => true, dependent: :destroy
has_one :lender, :autosave => true, dependent: :destroy
include UserSubclassMethods
# ...
end
module UserSubclassMethods
def method_missing(meth, *args, &blk)
super
rescue NoMethodError
if !errors[:user_mti_method_missing].any?
errors.add(:user_mti_method_missing, 'no method')
self.send(self.main_type.downcase).send(meth)
else
raise NoMethodError
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment