1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
# frozen-string-literal: true
require 'active_model'
module Sequel
module Plugins
# The active_model plugin makes Sequel::Model objects
# pass the ActiveModel::Lint tests, which should
# hopefully mean full ActiveModel compliance. This should
# allow the full support of Sequel::Model objects in Rails 3+.
# This plugin requires active_model in order to use
# ActiveModel::Naming.
#
# Usage:
#
# # Make all subclasses active_model compliant (called before loading subclasses)
# Sequel::Model.plugin :active_model
#
# # Make the Album class active_model compliant
# Album.plugin :active_model
module ActiveModel
# ActiveModel compliant error class
class Errors < Sequel::Model::Errors
# Add autovivification so that #[] always returns an array.
def [](k)
fetch(k){self[k] = []}
end
end
module ClassMethods
include ::ActiveModel::Naming
# Cache model_name and to_partial path value before freezing.
def freeze
model_name
_to_partial_path
super
end
# Class level cache for to_partial_path.
def _to_partial_path
@_to_partial_path ||= "#{underscore(pluralize(to_s))}/#{underscore(demodulize(to_s))}".freeze
end
end
module InstanceMethods
# Record that an object was destroyed, for later use by
# destroyed?
def after_destroy
super
@destroyed = true
end
# Return ::ActiveModel::Name instance for the class.
def model_name
model.model_name
end
# False if the object is new? or has been destroyed, true otherwise.
def persisted?
return false if new?
return false if defined?(@destroyed)
if defined?(@rollback_checker)
if @rollback_checker.call
return false
end
end
true
end
# An array of primary key values, or nil if the object is not persisted.
def to_key
if primary_key.is_a?(Symbol)
[pk] if pk
else
pk if pk.all?
end
end
# With the active_model plugin, Sequel model objects are already
# compliant, so this returns self.
def to_model
self
end
# An string representing the object's primary key. For composite
# primary keys, joins them with to_param_joiner.
def to_param
if persisted? and k = to_key
k.join(to_param_joiner)
end
end
# Returns a string identifying the path associated with the object.
def to_partial_path
model._to_partial_path
end
private
# For new objects, add a rollback checker to check if the transaction
# in which this instance is created is rolled back.
def _save(opts)
if new? && db.in_transaction?(opts)
@rollback_checker = db.rollback_checker(opts)
end
super
end
# Use ActiveModel compliant errors class.
def errors_class
Errors
end
# The string to use to join composite primary key param strings.
def to_param_joiner
'-'
end
end
end
end
end
|