lib/acts_as_ar_model.rb
class ActsAsArModel
include Vmdb::Logging
include ArVisibleAttribute
def self.connection
ActiveRecord::Base.connection
end
def connection
self.class.connection
end
def self.table_name
nil
end
def self.pluralize_table_names
false
end
def self.base_class
superclass == ActsAsArModel ? self : superclass.base_class
end
def self.includes_to_references(_inc)
[]
end
class << self; alias_method :base_model, :base_class; end
#
# Column methods
#
module FakeAttributeStore
extend ActiveSupport::Concern
# When ActiveRecord::Attributes gets [partially] extracted into
# ActiveModel (hopefully in 5.1), this should become redundant. For
# now, we'll just fake out the portion of the API we need.
#
# Based very heavily on matching methods in current ActiveRecord.
module ClassMethods
def load_schema
load_schema! if @attribute_types.nil?
end
def load_schema!
# no-op
end
def reload_schema_from_cache
@attribute_types = nil
end
def attribute_types
@attribute_types ||= Hash.new(ActiveModel::Type::Value.new)
end
def attribute_names
load_schema
attribute_types.keys
end
def has_attribute?(name)
load_schema
attribute_types.key?(name.to_s)
end
def type_for_attribute(attr_name)
load_schema
attribute_types[attr_name]
end
end
end
module AttributeBag
def initialize
@attributes = {}
end
def attributes=(values)
values.each do |attr, value|
send(:"#{attr}=", value)
end
end
def attributes
@attributes.dup
end
def [](attr)
@attributes[attr.to_s]
end
alias_method :read_attribute, :[]
def []=(attr, value)
@attributes[attr.to_s] = value
end
alias_method :write_attribute, :[]=
end
def self.set_columns_hash(hash)
hash[:id] ||= :integer
hash.each do |attribute, type|
virtual_attribute attribute, type
define_method(attribute) do
read_attribute(attribute)
end
define_method(:"#{attribute}=") do |val|
write_attribute(attribute, val)
end
end
end
include FakeAttributeStore
include ActiveRecord::VirtualAttributes::VirtualFields
include AttributeBag
def self.instances_are_derived?
true
end
def self.reflect_on_association(name)
virtual_reflection(name)
end
def initialize(values = {})
super()
self.attributes = values
end
#
# Reflection methods
#
def self.reflections
@reflections ||= {}
end
#
# Find routines
#
def self.find(*_args)
raise NotImplementedError, _("find must be implemented in a subclass")
end
# This method is called by QueryRelation upon executing the query.
# Since it will receive non-legacy search options, we need to convert
# them to handle the legacy find.
def self.search(mode, options = {})
find(mode, to_legacy_options(options))
end
private_class_method :search
def self.to_legacy_options(options)
{
:conditions => options[:where],
:include => options[:includes],
:limit => options[:limit],
:order => options[:order],
:offset => options[:offset],
:select => options[:select],
:group => options[:group],
}.delete_blanks
end
private_class_method :to_legacy_options
def self.all(*args)
require 'query_relation'
QueryRelation.new(self, *args)
end
def self.first(*args)
find(:first, *args)
end
def self.last(*args)
find(:last, *args)
end
def self.count(*args)
all(*args).count
end
def self.find_by_id(*id)
options = id.extract_options!
options[:conditions] = {:id => id.first}
first(options)
end
def self.find_all_by_id(*ids)
options = ids.extract_options!
options[:conditions] = {:id => ids.flatten}
all(options)
end
#
# Methods pulled from ActiveRecord 2.3.8
#
# Returns the contents of the record as a nicely formatted string.
def inspect
attributes_as_nice_string = self.class.attribute_names.collect do |name|
"#{name}: #{attribute_for_inspect(name)}"
end.compact.join(", ")
"#<#{self.class} #{attributes_as_nice_string}>"
end
private
# Returns an <tt>#inspect</tt>-like string for the value of the
# attribute +attr_name+. String attributes are elided after 50
# characters, and Date and Time attributes are returned in the
# <tt>:db</tt> format. Other attributes return the value of
# <tt>#inspect</tt> without modification.
#
# person = Person.create!(:name => "David Heinemeier Hansson " * 3)
#
# person.attribute_for_inspect(:name)
# # => '"David Heinemeier Hansson David Heinemeier Hansson D..."'
#
# person.attribute_for_inspect(:created_at)
# # => '"2009-01-12 04:48:57"'
def attribute_for_inspect(attr_name)
value = self[attr_name]
if value.kind_of?(String) && value.length > 50
"#{value[0..50]}...".inspect
elsif value.kind_of?(Date) || value.kind_of?(Time)
%("#{value.to_fs(:db)}")
else
value.inspect
end
end
end