validated_object 1.1.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 97d91eb8801c44a0daecab2f6bf5e66c1dc34908
4
- data.tar.gz: b53ae1848ed9176217969907ff95d4ceb6f0d06b
2
+ SHA256:
3
+ metadata.gz: beeec5e7c798a88c65b4f5a492ce3e59505dacf6a0a1f8de4da90ca59c73f873
4
+ data.tar.gz: 3c18ec02b076c71a020eaf7825fa2014321e09ee43a5490373698bfd8deb3c59
5
5
  SHA512:
6
- metadata.gz: 7df6a6cacb4a691183fe606828b572a74e08b139d136e8e6826e5fd2ff3f441443b2f4ef451da96a65040075a46ecfee7e123da9f1ed911308c26b586e0482fe
7
- data.tar.gz: 86ff719a5c3f23f76f843c049a1071b5ff79e6b20953ca482a3cedf33904adde167553d6efce284e067a0f69bb3841534f1bceb2d29a6bd01ed1dacd77bd8931
6
+ metadata.gz: 279331de46a2f201ee2eafcb1633ab0ad3b428fa7651276e7754a4e06b6a740f1c473fd14e6296d428d74e3ee39c962bdbcc0e0ebaf6f7bbc7a7fdd393bc56c1
7
+ data.tar.gz: afe9a3252da50c7bd028ebbfec81729e0ecf71e0c8c5ff1272d31e616593d41e031a87b11602cfb0337dac3c21d0abad1af024007757c3cab462df66c79fa163
@@ -1,5 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1
4
3
  - 2.2.2
5
- before_install: gem install bundler -v 1.10.6
4
+ - 2.3.1
5
+ - 2.7.1
6
+ before_install: gem install bundler
data/README.md CHANGED
@@ -1,28 +1,18 @@
1
- [![Gem Version](https://badge.fury.io/rb/validated_object.svg)](https://badge.fury.io/rb/validated_object) [![Build Status](https://travis-ci.org/dogweather/validated_object.svg?branch=master)](https://travis-ci.org/dogweather/validated_object) [![Code Climate](https://codeclimate.com/github/dogweather/validated_object/badges/gpa.svg)](https://codeclimate.com/github/dogweather/validated_object)
1
+ [![Gem Version](https://badge.fury.io/rb/validated_object.svg)](https://badge.fury.io/rb/validated_object) [![Build Status](https://travis-ci.org/public-law/validated_object.svg?branch=master)](https://travis-ci.org/public-law/validated_object) [![Code Climate](https://codeclimate.com/github/dogweather/validated_object/badges/gpa.svg)](https://codeclimate.com/github/dogweather/validated_object)
2
2
 
3
3
  # ValidatedObject
4
4
 
5
- Uses
6
- [ActiveModel::Validations](http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validates)
7
- to create self-validating Plain Old Ruby objects. I wrote it for helping with CSV data imports into my Rails apps.
8
- Very readable error messages are also important in that context, to track down parsing errors. This gem provides those too.
5
+ Plain Old Ruby Objects + Rails Validations = **self-checking Ruby objects**.
9
6
 
10
7
 
11
- ## Installation
8
+ ## Goals
12
9
 
13
- Add this line to your application's Gemfile:
10
+ * Very readable error messages
11
+ * Clean, minimal syntax
14
12
 
15
- ```ruby
16
- gem 'validated_object'
17
- ```
13
+ This is a small layer around
14
+ [ActiveModel::Validations](http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validates). (About 18 lines of code.) So if you know how to use Rails Validations, you're good to go. I wrote this to help with CSV data imports and [website microdata generation](https://github.com/dogweather/schema-dot-org).
18
15
 
19
- And then execute:
20
-
21
- $ bundle
22
-
23
- Or install it yourself as:
24
-
25
- $ gem install validated_object
26
16
 
27
17
  ## Usage
28
18
 
@@ -33,47 +23,119 @@ All of the [ActiveModel::Validations](http://api.rubyonrails.org/classes/ActiveM
33
23
 
34
24
  ```ruby
35
25
  class Dog < ValidatedObject::Base
36
- attr_accessor :name, :birthday
26
+ # Plain old Ruby
27
+ attr_accessor :name, :birthday # attr_reader is supported as well for read-only attributes
37
28
 
29
+ # Plain old Rails
38
30
  validates :name, presence: true
39
- validates :birthday, type: Date, allow_nil: true
31
+
32
+ # A new type-validation if you'd like to use it
33
+ validates :birthday, type: Date, allow_nil: true # Strongly typed but optional
40
34
  end
41
35
  ```
42
36
 
37
+ The included `TypeValidator` is what enables `type: Date`, above. All classes can be checked, as well as a pseudo-class `Boolean`. E.g.:
38
+
39
+ ```ruby
40
+ #...
41
+ validates :premium_membership, type: Boolean
42
+ #...
43
+ ```
44
+
43
45
  ### Instantiating and automatically validating
44
46
 
45
47
  ```ruby
46
- # The dog1 instance validates itself at the end of instantiation.
47
- # Here, it succeeds and so doesn't raise an exception.
48
- dog1 = Dog.new do |d|
49
- d.name = 'Spot'
50
- end
48
+ # This Dog instance validates itself at the end of instantiation.
49
+ spot = Dog.new(name: 'Spot')
50
+ ```
51
51
 
52
- # We can also explicitly test for validity
53
- dog1.valid? # => true
52
+ ```ruby
53
+ # We can also explicitly test for validity because all of
54
+ # ActiveModel::Validations is available.
55
+ spot.valid? # => true
54
56
 
55
- dog1.birthday = Date.new(2015, 1, 23)
56
- dog1.valid? # => true
57
+ spot.birthday = Date.new(2015, 1, 23)
58
+ spot.valid? # => true
57
59
  ```
58
60
 
59
- ### Making an instance _invalid_
61
+ ### Good error messages
62
+
63
+ Any of the standard Validations methods can be
64
+ used to test an instance, plus the custom `check_validations!` convenience method:
60
65
 
61
66
  ```ruby
62
- dog1.birthday = '2015-01-23'
63
- dog1.valid? # => false
64
- dog1.check_validations! # => ArgumentError: Birthday is class String, not Date
67
+ spot.birthday = '2015-01-23'
68
+ spot.valid? # => false
69
+ spot.check_validations! # => ArgumentError: Birthday is a String, not a Date
65
70
  ```
66
71
 
72
+ Note the clear, explicit error message. These are great when reading a log
73
+ file following a data import. It describes all the invalid conditions. Let's
74
+ test it by making another attribute invalid:
75
+
76
+ ```ruby
77
+ spot.name = nil
78
+ spot.check_validations! # => ArgumentError: Name can't be blank; Birthday is a String, not a Date
79
+ ```
80
+
81
+
82
+ ### Use in parsing data
83
+
84
+ I often use a validated object in a loop to import data, e.g.:
85
+
86
+ ```ruby
87
+ # Import a CSV file of dogs
88
+ dogs = []
89
+ csv.next_row do |row|
90
+ begin
91
+ dogs << Dog.new(name: row.name)
92
+ rescue ArgumentError => e
93
+ logger.warn(e)
94
+ end
95
+ end
96
+ ```
97
+
98
+ The result is that `dogs` is an array of guaranteed valid Dog objects. And the
99
+ error log lists unparseable rows with good info for tracking down problems in
100
+ the data.
101
+
102
+ ### Use in code generation
103
+
104
+ My [Schema.org microdata generation gem](https://github.com/dogweather/schema-dot-org) uses ValidatedObjects to recursively create well formed HTML / JSON-LD.
105
+
106
+ ## Installation
107
+
108
+ Add this line to your application's Gemfile:
109
+
110
+ ```ruby
111
+ gem 'validated_object'
112
+ ```
113
+
114
+ And then execute:
115
+
116
+ $ bundle
117
+
118
+ Or install it yourself as:
119
+
120
+ $ gem install validated_object
121
+
122
+
67
123
 
68
124
  ## Development
69
125
 
70
- (TODO: Verify these instructions.) After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
126
+ (TODO: Verify these instructions.) After checking out the repo, run `bin/setup`
127
+ to install dependencies. Then, run `rake spec` to run the tests. You can also
128
+ run `bin/console` for an interactive prompt that will allow you to experiment.
71
129
 
72
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
130
+ To install this gem onto your local machine, run `bundle exec rake install`. To
131
+ release a new version, update the version number in `version.rb`, and then run
132
+ `bundle exec rake release`, which will create a git tag for the version, push
133
+ git commits and tags, and push the `.gem` file to
134
+ [rubygems.org](https://rubygems.org).
73
135
 
74
136
  ## Contributing
75
137
 
76
- Bug reports and pull requests are welcome on GitHub at https://github.com/dogweather/validated_object.
138
+ Bug reports and pull requests are welcome on GitHub.
77
139
 
78
140
 
79
141
  ## License
@@ -1,11 +1,15 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
1
4
  require 'active_model'
5
+ require 'sorbet-runtime'
2
6
  require 'validated_object/version'
3
7
 
4
8
  module ValidatedObject
5
9
  # @abstract Subclass and add `attr_accessor` and validations
6
10
  # to create custom validating objects.
7
11
  #
8
- # Uses [ActiveModel::Validations](http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validates)
12
+ # Uses {http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validates ActiveModel::Validations}
9
13
  # to create self-validating Plain Old Ruby objects. This is especially
10
14
  # useful when importing data from one system into another. This class also
11
15
  # creates very readable error messages.
@@ -21,9 +25,7 @@ module ValidatedObject
21
25
  # @example Instantiating and automatically validating
22
26
  # # The dog1 instance validates itself at the end of instantiation.
23
27
  # # Here, it succeeds and so doesn't raise an exception.
24
- # dog1 = Dog.new do |d|
25
- # d.name = 'Spot'
26
- # end
28
+ # dog1 = Dog.new name: 'Spot'
27
29
  #
28
30
  # # We can also explicitly test for validity
29
31
  # dog1.valid? # => true
@@ -41,28 +43,41 @@ module ValidatedObject
41
43
  # @see http://www.rubyinside.com/rails-3-0s-activemodel-how-to-give-ruby-classes-some-activerecord-magic-2937.html Rails 3.0′s ActiveModel: How To Give Ruby Classes Some ActiveRecord Magic, Peter Cooper
42
44
  class Base
43
45
  include ActiveModel::Validations
46
+ extend T::Sig
47
+
48
+ SymbolHash = T.type_alias { T::Hash[Symbol, T.untyped] }
49
+
50
+ EMPTY_HASH = T.let({}.freeze, SymbolHash)
44
51
 
45
- # Implements a pseudo-boolean class.
52
+ # A private class definition, not intended to
53
+ # be used directly. Implements a pseudo-boolean class
54
+ # enabling validations like this:
55
+ #
56
+ # validates :enabled, type: Boolean
46
57
  class Boolean
47
58
  end
48
59
 
49
60
  # Instantiate and validate a new object.
50
- #
51
- # @yieldparam [ValidatedObject] new_object the yielded new object
52
- # for configuration.
61
+ # @example
62
+ # maru = Dog.new(birthday: Date.today, name: 'Maru')
53
63
  #
54
64
  # @raise [ArgumentError] if the object is not valid at the
55
- # end of initialization.
56
- def initialize
57
- yield(self)
65
+ # end of initialization or `attributes` is not a Hash.
66
+ sig { params(attributes: SymbolHash).returns(ValidatedObject::Base)}
67
+ def initialize(attributes = EMPTY_HASH)
68
+ set_instance_variables from_hash: attributes
58
69
  check_validations!
59
70
  self
60
71
  end
61
72
 
62
73
  # Run any validations and raise an error if invalid.
74
+ #
63
75
  # @raise [ArgumentError] if any validations fail.
76
+ # @return [ValidatedObject::Base] the receiver
77
+ sig {returns(ValidatedObject::Base)}
64
78
  def check_validations!
65
79
  raise ArgumentError, errors.full_messages.join('; ') if invalid?
80
+
66
81
  self
67
82
  end
68
83
 
@@ -70,25 +85,79 @@ module ValidatedObject
70
85
  # or a subclass. It supports a pseudo-boolean class for convenient
71
86
  # validation. (Ruby doesn't have a built-in Boolean.)
72
87
  #
88
+ # Automatically used in a `type` validation:
89
+ #
73
90
  # @example Ensure that weight is a number
74
91
  # class Dog < ValidatedObject::Base
75
92
  # attr_accessor :weight, :neutered
76
- # validates :weight, type: Numeric
77
- # validates :neutered, type: Boolean
93
+ # validates :weight, type: Numeric # Typed and required
94
+ # validates :neutered, type: Boolean, allow_nil: true # Typed but optional
78
95
  # end
79
96
  class TypeValidator < ActiveModel::EachValidator
97
+ extend T::Sig
98
+
80
99
  # @return [nil]
100
+ sig do
101
+ params(
102
+ record: T.untyped,
103
+ attribute: T.untyped,
104
+ value: T.untyped
105
+ )
106
+ .void
107
+ end
81
108
  def validate_each(record, attribute, value)
82
- expected_class = options[:with]
109
+ validation_options = T.let(options, SymbolHash)
110
+
111
+ expected_class = validation_options[:with]
112
+
113
+ return if pseudo_boolean?(expected_class, value) ||
114
+ expected_class?(expected_class, value)
115
+
116
+ save_error(record, attribute, value, validation_options)
117
+ end
118
+
119
+ private
120
+
121
+ sig {params(expected_class: T.untyped, value: T.untyped).returns(T.untyped)}
122
+ def pseudo_boolean?(expected_class, value)
123
+ expected_class == Boolean && boolean?(value)
124
+ end
125
+
126
+ sig {params(expected_class: T.untyped, value: T.untyped).returns(T.untyped)}
127
+ def expected_class?(expected_class, value)
128
+ value.is_a?(expected_class)
129
+ end
130
+
131
+ sig {params(value: T.untyped).returns(T.untyped)}
132
+ def boolean?(value)
133
+ value.is_a?(TrueClass) || value.is_a?(FalseClass)
134
+ end
135
+
136
+ sig do
137
+ params(
138
+ record: T.untyped,
139
+ attribute: T.untyped,
140
+ value: T.untyped,
141
+ validation_options: SymbolHash
142
+ )
143
+ .void
144
+ end
145
+ def save_error(record, attribute, value, validation_options)
146
+ record.errors.add attribute,
147
+ validation_options[:message] || "is a #{value.class}, not a #{validation_options[:with]}"
148
+ end
149
+ end
150
+
151
+ private
83
152
 
84
- if expected_class == Boolean
85
- return if value.is_a?(TrueClass) || value.is_a?(FalseClass)
86
- else
87
- return if value.is_a?(expected_class)
88
- end
153
+ sig {params(from_hash: SymbolHash).void}
154
+ def set_instance_variables(from_hash:)
155
+ from_hash.each do |variable_name, variable_value|
156
+ # Test for the attribute reader
157
+ send variable_name.to_sym
89
158
 
90
- msg = options[:message] || "is class #{value.class}, not #{expected_class}"
91
- record.errors.add attribute, msg
159
+ # Set value in a way that succeeds even if attr is read-only
160
+ instance_variable_set "@#{variable_name}".to_sym, variable_value
92
161
  end
93
162
  end
94
163
  end
@@ -1,3 +1,6 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
1
4
  module ValidatedObject
2
- VERSION = '1.1.0'.freeze
5
+ VERSION = '2.1.0'
3
6
  end
@@ -0,0 +1,18 @@
1
+ # typed: ignore
2
+ require 'date'
3
+ require 'validated_object'
4
+
5
+ class Dog < ValidatedObject::Base
6
+ attr_reader :name, :birthday
7
+ validates :name, presence: true
8
+ validates :birthday, type: Date, allow_nil: true
9
+ end
10
+
11
+ phoebe = Dog.new(name: 'Phoebe')
12
+ puts phoebe.inspect
13
+
14
+ maru = Dog.new(birthday: Date.today, name: 'Maru')
15
+ puts maru.inspect
16
+
17
+ hiro = Dog.new(birthday: 'today')
18
+ puts hiro.inspect
@@ -0,0 +1,2 @@
1
+ --dir
2
+ .
@@ -0,0 +1,210 @@
1
+ # This file is autogenerated. Do not edit it by hand. Regenerate it with:
2
+ # srb rbi gems
3
+
4
+ # typed: ignore
5
+ #
6
+ # If you would like to make changes to this file, great! Please create the gem's shim here:
7
+ #
8
+ # https://github.com/sorbet/sorbet-typed/new/master?filename=lib/activemodel/all/activemodel.rbi
9
+ #
10
+ # activemodel-6.0.3.2
11
+
12
+ module ActiveModel
13
+ def self.eager_load!; end
14
+ def self.gem_version; end
15
+ def self.version; end
16
+ extend ActiveSupport::Autoload
17
+ end
18
+ module ActiveModel::VERSION
19
+ end
20
+ module ActiveModel::Serializers
21
+ extend ActiveSupport::Autoload
22
+ end
23
+ module ActiveModel::Validations
24
+ def errors; end
25
+ def initialize_dup(other); end
26
+ def invalid?(context = nil); end
27
+ def raise_validation_error; end
28
+ def read_attribute_for_validation(*arg0); end
29
+ def run_validations!; end
30
+ def valid?(context = nil); end
31
+ def validate!(context = nil); end
32
+ def validate(context = nil); end
33
+ def validates_with(*args, &block); end
34
+ extend ActiveSupport::Concern
35
+ end
36
+ module ActiveModel::Validations::ClassMethods
37
+ def _parse_validates_options(options); end
38
+ def _validates_default_keys; end
39
+ def attribute_method?(attribute); end
40
+ def clear_validators!; end
41
+ def inherited(base); end
42
+ def validate(*args, &block); end
43
+ def validates!(*attributes); end
44
+ def validates(*attributes); end
45
+ def validates_each(*attr_names, &block); end
46
+ def validates_with(*args, &block); end
47
+ def validators; end
48
+ def validators_on(*attributes); end
49
+ end
50
+ module ActiveModel::Validations::Clusivity
51
+ def check_validity!; end
52
+ def delimiter; end
53
+ def include?(record, value); end
54
+ def inclusion_method(enumerable); end
55
+ end
56
+ class ActiveModel::Validator
57
+ def initialize(options = nil); end
58
+ def kind; end
59
+ def options; end
60
+ def self.kind; end
61
+ def validate(record); end
62
+ end
63
+ class ActiveModel::EachValidator < ActiveModel::Validator
64
+ def attributes; end
65
+ def check_validity!; end
66
+ def initialize(options); end
67
+ def validate(record); end
68
+ def validate_each(record, attribute, value); end
69
+ end
70
+ class ActiveModel::BlockValidator < ActiveModel::EachValidator
71
+ def initialize(options, &block); end
72
+ def validate_each(record, attribute, value); end
73
+ end
74
+ class ActiveModel::Validations::InclusionValidator < ActiveModel::EachValidator
75
+ def validate_each(record, attribute, value); end
76
+ include ActiveModel::Validations::Clusivity
77
+ end
78
+ module ActiveModel::Validations::HelperMethods
79
+ def _merge_attributes(attr_names); end
80
+ def validates_absence_of(*attr_names); end
81
+ def validates_acceptance_of(*attr_names); end
82
+ def validates_confirmation_of(*attr_names); end
83
+ def validates_exclusion_of(*attr_names); end
84
+ def validates_format_of(*attr_names); end
85
+ def validates_inclusion_of(*attr_names); end
86
+ def validates_length_of(*attr_names); end
87
+ def validates_numericality_of(*attr_names); end
88
+ def validates_presence_of(*attr_names); end
89
+ def validates_size_of(*attr_names); end
90
+ end
91
+ class ActiveModel::Validations::AbsenceValidator < ActiveModel::EachValidator
92
+ def validate_each(record, attr_name, value); end
93
+ end
94
+ class ActiveModel::Validations::NumericalityValidator < ActiveModel::EachValidator
95
+ def allow_only_integer?(record); end
96
+ def check_validity!; end
97
+ def filtered_options(value); end
98
+ def is_hexadecimal_literal?(raw_value); end
99
+ def is_integer?(raw_value); end
100
+ def is_number?(raw_value); end
101
+ def parse_as_number(raw_value); end
102
+ def record_attribute_changed_in_place?(record, attr_name); end
103
+ def validate_each(record, attr_name, value); end
104
+ end
105
+ module ActiveModel::Validations::Callbacks
106
+ def run_validations!; end
107
+ extend ActiveSupport::Concern
108
+ end
109
+ module ActiveModel::Validations::Callbacks::ClassMethods
110
+ def after_validation(*args, &block); end
111
+ def before_validation(*args, &block); end
112
+ end
113
+ class ActiveModel::Validations::ExclusionValidator < ActiveModel::EachValidator
114
+ def validate_each(record, attribute, value); end
115
+ include ActiveModel::Validations::Clusivity
116
+ end
117
+ class ActiveModel::Validations::ConfirmationValidator < ActiveModel::EachValidator
118
+ def confirmation_value_equal?(record, attribute, value, confirmed); end
119
+ def initialize(options); end
120
+ def setup!(klass); end
121
+ def validate_each(record, attribute, value); end
122
+ end
123
+ class ActiveModel::Validations::FormatValidator < ActiveModel::EachValidator
124
+ def check_options_validity(name); end
125
+ def check_validity!; end
126
+ def option_call(record, name); end
127
+ def record_error(record, attribute, name, value); end
128
+ def regexp_using_multiline_anchors?(regexp); end
129
+ def validate_each(record, attribute, value); end
130
+ end
131
+ class ActiveModel::Validations::PresenceValidator < ActiveModel::EachValidator
132
+ def validate_each(record, attr_name, value); end
133
+ end
134
+ class ActiveModel::Validations::LengthValidator < ActiveModel::EachValidator
135
+ def check_validity!; end
136
+ def initialize(options); end
137
+ def skip_nil_check?(key); end
138
+ def validate_each(record, attribute, value); end
139
+ end
140
+ class ActiveModel::Validations::AcceptanceValidator < ActiveModel::EachValidator
141
+ def acceptable_option?(value); end
142
+ def initialize(options); end
143
+ def setup!(klass); end
144
+ def validate_each(record, attribute, value); end
145
+ end
146
+ class ActiveModel::Validations::AcceptanceValidator::LazilyDefineAttributes < Module
147
+ def ==(other); end
148
+ def attributes; end
149
+ def define_on(klass); end
150
+ def included(klass); end
151
+ def initialize(attributes); end
152
+ def matches?(method_name); end
153
+ end
154
+ class ActiveModel::Validations::WithValidator < ActiveModel::EachValidator
155
+ def validate_each(record, attr, val); end
156
+ end
157
+ class ActiveModel::ValidationError < StandardError
158
+ def initialize(model); end
159
+ def model; end
160
+ end
161
+ class ActiveModel::Name
162
+ def !~(**, &&); end
163
+ def <=>(**, &&); end
164
+ def ==(arg); end
165
+ def ===(arg); end
166
+ def =~(**, &&); end
167
+ def _singularize(string); end
168
+ def as_json(**, &&); end
169
+ def cache_key; end
170
+ def collection; end
171
+ def element; end
172
+ def eql?(**, &&); end
173
+ def human(options = nil); end
174
+ def i18n_key; end
175
+ def initialize(klass, namespace = nil, name = nil); end
176
+ def match?(**, &&); end
177
+ def name; end
178
+ def param_key; end
179
+ def plural; end
180
+ def route_key; end
181
+ def singular; end
182
+ def singular_route_key; end
183
+ def to_s(**, &&); end
184
+ def to_str(**, &&); end
185
+ include Comparable
186
+ end
187
+ module ActiveModel::Naming
188
+ def model_name; end
189
+ def self.extended(base); end
190
+ def self.model_name_from_record_or_class(record_or_class); end
191
+ def self.param_key(record_or_class); end
192
+ def self.plural(record_or_class); end
193
+ def self.route_key(record_or_class); end
194
+ def self.singular(record_or_class); end
195
+ def self.singular_route_key(record_or_class); end
196
+ def self.uncountable?(record_or_class); end
197
+ end
198
+ module ActiveModel::Callbacks
199
+ def _define_after_model_callback(klass, callback); end
200
+ def _define_around_model_callback(klass, callback); end
201
+ def _define_before_model_callback(klass, callback); end
202
+ def define_model_callbacks(*callbacks); end
203
+ def self.extended(base); end
204
+ end
205
+ module ActiveModel::Translation
206
+ def human_attribute_name(attribute, options = nil); end
207
+ def i18n_scope; end
208
+ def lookup_ancestors; end
209
+ include ActiveModel::Naming
210
+ end