activeentity 0.0.1.beta14 → 0.0.1.beta15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +4 -4
- data/Rakefile +7 -7
- data/lib/active_entity.rb +29 -7
- data/lib/active_entity/aggregations.rb +2 -1
- data/lib/active_entity/associations.rb +46 -24
- data/lib/active_entity/associations/{embedded → embeds}/association.rb +2 -2
- data/lib/active_entity/associations/{embedded → embeds}/builder/association.rb +1 -1
- data/lib/active_entity/associations/{embedded → embeds}/builder/collection_association.rb +1 -1
- data/lib/active_entity/associations/{embedded → embeds}/builder/embedded_in.rb +1 -1
- data/lib/active_entity/associations/{embedded → embeds}/builder/embeds_many.rb +1 -1
- data/lib/active_entity/associations/{embedded → embeds}/builder/embeds_one.rb +1 -1
- data/lib/active_entity/associations/{embedded → embeds}/builder/singular_association.rb +1 -1
- data/lib/active_entity/associations/{embedded → embeds}/collection_association.rb +1 -1
- data/lib/active_entity/associations/{embedded → embeds}/collection_proxy.rb +2 -2
- data/lib/active_entity/associations/{embedded → embeds}/embedded_in_association.rb +1 -1
- data/lib/active_entity/associations/{embedded → embeds}/embeds_many_association.rb +1 -1
- data/lib/active_entity/associations/{embedded → embeds}/embeds_one_association.rb +2 -1
- data/lib/active_entity/associations/{embedded → embeds}/singular_association.rb +1 -1
- data/lib/active_entity/attribute_assignment.rb +9 -3
- data/lib/active_entity/attribute_methods.rb +12 -11
- data/lib/active_entity/attribute_methods/before_type_cast.rb +1 -1
- data/lib/active_entity/attribute_methods/dirty.rb +13 -0
- data/lib/active_entity/attribute_methods/primary_key.rb +1 -1
- data/lib/active_entity/attribute_methods/query.rb +11 -4
- data/lib/active_entity/attribute_methods/read.rb +1 -3
- data/lib/active_entity/attribute_methods/time_zone_conversion.rb +2 -0
- data/lib/active_entity/attribute_methods/write.rb +4 -6
- data/lib/active_entity/attributes.rb +76 -2
- data/lib/active_entity/base.rb +3 -12
- data/lib/active_entity/core.rb +97 -39
- data/lib/active_entity/define_callbacks.rb +4 -0
- data/lib/active_entity/enum.rb +30 -4
- data/lib/active_entity/errors.rb +0 -11
- data/lib/active_entity/gem_version.rb +1 -1
- data/lib/active_entity/inheritance.rb +4 -106
- data/lib/active_entity/integration.rb +1 -1
- data/lib/active_entity/model_schema.rb +0 -12
- data/lib/active_entity/nested_attributes.rb +5 -12
- data/lib/active_entity/railtie.rb +61 -1
- data/lib/active_entity/readonly_attributes.rb +9 -1
- data/lib/active_entity/reflection.rb +22 -19
- data/lib/active_entity/serialization.rb +9 -6
- data/lib/active_entity/store.rb +51 -2
- data/lib/active_entity/type.rb +8 -8
- data/lib/active_entity/type/registry.rb +5 -5
- data/lib/active_entity/{validate_embedded_association.rb → validate_embeds_association.rb} +6 -6
- data/lib/active_entity/validations.rb +2 -6
- data/lib/active_entity/validations/associated.rb +1 -1
- data/lib/active_entity/validations/{uniqueness_in_embedding.rb → uniqueness_in_embeds.rb} +1 -1
- data/lib/active_entity/validations/uniqueness_on_active_record.rb +46 -40
- metadata +27 -30
- data/lib/active_entity/type/decimal_without_scale.rb +0 -15
- data/lib/active_entity/type/hash_lookup_type_map.rb +0 -25
- data/lib/active_entity/type/type_map.rb +0 -62
- data/lib/tasks/active_entity_tasks.rake +0 -6
@@ -1,6 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveEntity
|
4
|
+
# This module exists because ActiveEntity::AttributeMethods::Dirty needs to
|
5
|
+
# define callbacks, but continue to have its version of +save+ be the super
|
6
|
+
# method of ActiveEntity::Callbacks. This will be removed when the removal
|
7
|
+
# of deprecated code removes this need.
|
4
8
|
module DefineCallbacks
|
5
9
|
extend ActiveSupport::Concern
|
6
10
|
|
data/lib/active_entity/enum.rb
CHANGED
@@ -27,6 +27,32 @@ module ActiveEntity
|
|
27
27
|
# conversation.status.nil? # => true
|
28
28
|
# conversation.status # => nil
|
29
29
|
#
|
30
|
+
# Scopes based on the allowed values of the enum field will be provided
|
31
|
+
# as well. With the above example:
|
32
|
+
#
|
33
|
+
# Conversation.active
|
34
|
+
# Conversation.not_active
|
35
|
+
# Conversation.archived
|
36
|
+
# Conversation.not_archived
|
37
|
+
#
|
38
|
+
# Of course, you can also query them directly if the scopes don't fit your
|
39
|
+
# needs:
|
40
|
+
#
|
41
|
+
# Conversation.where(status: [:active, :archived])
|
42
|
+
# Conversation.where.not(status: :active)
|
43
|
+
#
|
44
|
+
# Defining scopes can be disabled by setting +:_scopes+ to +false+.
|
45
|
+
#
|
46
|
+
# class Conversation < ActiveEntity::Base
|
47
|
+
# enum status: [ :active, :archived ], _scopes: false
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# You can set the default value from the database declaration, like:
|
51
|
+
#
|
52
|
+
# create_table :conversations do |t|
|
53
|
+
# t.column :status, :integer, default: 0
|
54
|
+
# end
|
55
|
+
#
|
30
56
|
# Good practice is to let the first declared status be the default.
|
31
57
|
#
|
32
58
|
# Finally, it's also possible to explicitly map the relation between attribute and
|
@@ -97,12 +123,12 @@ module ActiveEntity
|
|
97
123
|
end
|
98
124
|
|
99
125
|
def cast(value)
|
100
|
-
return if value.blank?
|
101
|
-
|
102
126
|
if mapping.has_key?(value)
|
103
127
|
value.to_s
|
104
128
|
elsif mapping.has_value?(value)
|
105
129
|
mapping.key(value)
|
130
|
+
elsif value.blank?
|
131
|
+
nil
|
106
132
|
else
|
107
133
|
assert_valid_value(value)
|
108
134
|
end
|
@@ -124,6 +150,7 @@ module ActiveEntity
|
|
124
150
|
end
|
125
151
|
|
126
152
|
private
|
153
|
+
|
127
154
|
attr_reader :name, :mapping, :subtype
|
128
155
|
end
|
129
156
|
|
@@ -182,6 +209,7 @@ module ActiveEntity
|
|
182
209
|
end
|
183
210
|
|
184
211
|
private
|
212
|
+
|
185
213
|
def _enum_methods_module
|
186
214
|
@_enum_methods_module ||= begin
|
187
215
|
mod = Module.new
|
@@ -212,8 +240,6 @@ module ActiveEntity
|
|
212
240
|
def detect_enum_conflict!(enum_name, method_name, klass_method = false)
|
213
241
|
if klass_method && dangerous_class_method?(method_name)
|
214
242
|
raise_conflict_error(enum_name, method_name, type: "class")
|
215
|
-
# elsif klass_method && method_defined_within?(method_name, Relation)
|
216
|
-
# raise_conflict_error(enum_name, method_name, type: "class", source: Relation.name)
|
217
243
|
elsif !klass_method && dangerous_attribute_method?(method_name)
|
218
244
|
raise_conflict_error(enum_name, method_name)
|
219
245
|
elsif !klass_method && method_defined_within?(method_name, _enum_methods_module, Module)
|
data/lib/active_entity/errors.rb
CHANGED
@@ -7,13 +7,6 @@ module ActiveEntity
|
|
7
7
|
class ActiveEntityError < StandardError
|
8
8
|
end
|
9
9
|
|
10
|
-
# Raised when the single-table inheritance mechanism fails to locate the subclass
|
11
|
-
# (for example due to improper usage of column that
|
12
|
-
# {ActiveEntity::Base.inheritance_attribute}[rdoc-ref:ModelSchema::ClassMethods#inheritance_attribute]
|
13
|
-
# points to).
|
14
|
-
class SubclassNotFound < ActiveEntityError
|
15
|
-
end
|
16
|
-
|
17
10
|
# Raised when an object assigned to an association has an incorrect type.
|
18
11
|
#
|
19
12
|
# class Ticket < ActiveEntity::Base
|
@@ -41,10 +34,6 @@ module ActiveEntity
|
|
41
34
|
class ConfigurationError < ActiveEntityError
|
42
35
|
end
|
43
36
|
|
44
|
-
# Raised on attempt to update record that is instantiated as read only.
|
45
|
-
class ReadOnlyRecord < ActiveEntityError
|
46
|
-
end
|
47
|
-
|
48
37
|
# Raised when attribute has a name reserved by Active Entity (when attribute
|
49
38
|
# has name of one of Active Entity instance methods).
|
50
39
|
class DangerousAttributeError < ActiveEntityError
|
@@ -6,7 +6,7 @@ module ActiveEntity
|
|
6
6
|
# == Single table inheritance
|
7
7
|
#
|
8
8
|
# Active Entity allows inheritance by storing the name of the class in a column that by
|
9
|
-
# default is named "type" (can be changed by overwriting <tt>Base.
|
9
|
+
# default is named "type" (can be changed by overwriting <tt>Base.inheritance_column</tt>).
|
10
10
|
# This means that an inheritance looking like this:
|
11
11
|
#
|
12
12
|
# class Company < ActiveEntity::Base; end
|
@@ -37,12 +37,6 @@ module ActiveEntity
|
|
37
37
|
module Inheritance
|
38
38
|
extend ActiveSupport::Concern
|
39
39
|
|
40
|
-
included do
|
41
|
-
# Determines whether to store the full constant name including namespace when using STI.
|
42
|
-
# This is true, by default.
|
43
|
-
class_attribute :store_full_sti_class, instance_writer: false, default: true
|
44
|
-
end
|
45
|
-
|
46
40
|
module ClassMethods
|
47
41
|
# Determines if one of the attributes passed in is the inheritance column,
|
48
42
|
# and if the inheritance column is attr accessible, it initializes an
|
@@ -52,19 +46,7 @@ module ActiveEntity
|
|
52
46
|
raise NotImplementedError, "#{self} is an abstract class and cannot be instantiated."
|
53
47
|
end
|
54
48
|
|
55
|
-
|
56
|
-
subclass = subclass_from_attributes(attributes)
|
57
|
-
|
58
|
-
if subclass.nil? && base_class?
|
59
|
-
subclass = subclass_from_attributes(_default_attributes)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
if subclass && subclass != self
|
64
|
-
subclass.new(attributes, &block)
|
65
|
-
else
|
66
|
-
super
|
67
|
-
end
|
49
|
+
super
|
68
50
|
end
|
69
51
|
|
70
52
|
# Returns +true+ if this does not need STI type condition. Returns
|
@@ -75,15 +57,10 @@ module ActiveEntity
|
|
75
57
|
elsif superclass.abstract_class?
|
76
58
|
superclass.descends_from_active_entity?
|
77
59
|
else
|
78
|
-
superclass == Base
|
60
|
+
superclass == Base
|
79
61
|
end
|
80
62
|
end
|
81
63
|
|
82
|
-
def finder_needs_type_condition? #:nodoc:
|
83
|
-
# This is like this because benchmarking justifies the strange :false stuff
|
84
|
-
:true == (@finder_needs_type_condition ||= descends_from_active_entity? ? :false : :true)
|
85
|
-
end
|
86
|
-
|
87
64
|
# Returns the class descending directly from ActiveEntity::Base, or
|
88
65
|
# an abstract class, if any, in the inheritance hierarchy.
|
89
66
|
#
|
@@ -94,7 +71,7 @@ module ActiveEntity
|
|
94
71
|
# and C.base_class would return B as the answer since A is an abstract_class.
|
95
72
|
def base_class
|
96
73
|
unless self < Base
|
97
|
-
raise ActiveEntityError, "#{name} doesn't belong in a hierarchy descending from
|
74
|
+
raise ActiveEntityError, "#{name} doesn't belong in a hierarchy descending from ActiveEntity"
|
98
75
|
end
|
99
76
|
|
100
77
|
if superclass == Base || superclass.abstract_class?
|
@@ -158,10 +135,6 @@ module ActiveEntity
|
|
158
135
|
defined?(@abstract_class) && @abstract_class == true
|
159
136
|
end
|
160
137
|
|
161
|
-
def sti_name
|
162
|
-
store_full_sti_class ? name : name.demodulize
|
163
|
-
end
|
164
|
-
|
165
138
|
def inherited(subclass)
|
166
139
|
subclass.instance_variable_set(:@_type_candidates_cache, Concurrent::Map.new)
|
167
140
|
super
|
@@ -198,81 +171,6 @@ module ActiveEntity
|
|
198
171
|
raise NameError.new("uninitialized constant #{candidates.first}", candidates.first)
|
199
172
|
end
|
200
173
|
end
|
201
|
-
|
202
|
-
private
|
203
|
-
|
204
|
-
# Called by +instantiate+ to decide which class to use for a new
|
205
|
-
# record instance. For single-table inheritance, we check the record
|
206
|
-
# for a +type+ column and return the corresponding class.
|
207
|
-
def discriminate_class_for_record(record)
|
208
|
-
if using_single_table_inheritance?(record)
|
209
|
-
find_sti_class(record[inheritance_attribute])
|
210
|
-
else
|
211
|
-
super
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
def using_single_table_inheritance?(record)
|
216
|
-
record[inheritance_attribute].present? && has_attribute?(inheritance_attribute)
|
217
|
-
end
|
218
|
-
|
219
|
-
def find_sti_class(type_name)
|
220
|
-
type_name = base_class.type_for_attribute(inheritance_attribute).cast(type_name)
|
221
|
-
subclass = begin
|
222
|
-
if store_full_sti_class
|
223
|
-
ActiveSupport::Dependencies.constantize(type_name)
|
224
|
-
else
|
225
|
-
compute_type(type_name)
|
226
|
-
end
|
227
|
-
rescue NameError
|
228
|
-
raise SubclassNotFound,
|
229
|
-
"The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " \
|
230
|
-
"This error is raised because the attribute '#{inheritance_attribute}' is reserved for storing the class in case of inheritance. " \
|
231
|
-
"Please rename this attribute if you didn't intend it to be used for storing the inheritance class " \
|
232
|
-
"or overwrite #{name}.inheritance_attribute to use another attribute for that information."
|
233
|
-
end
|
234
|
-
unless subclass == self || descendants.include?(subclass)
|
235
|
-
raise SubclassNotFound, "Invalid single-table inheritance type: #{subclass.name} is not a subclass of #{name}"
|
236
|
-
end
|
237
|
-
subclass
|
238
|
-
end
|
239
|
-
|
240
|
-
# Detect the subclass from the inheritance column of attrs. If the inheritance column value
|
241
|
-
# is not self or a valid subclass, raises ActiveEntity::SubclassNotFound
|
242
|
-
def subclass_from_attributes(attrs)
|
243
|
-
attrs = attrs.to_h if attrs.respond_to?(:permitted?)
|
244
|
-
if attrs.is_a?(Hash)
|
245
|
-
subclass_name = attrs[inheritance_attribute] || attrs[inheritance_attribute.to_sym]
|
246
|
-
|
247
|
-
if subclass_name.present?
|
248
|
-
find_sti_class(subclass_name)
|
249
|
-
end
|
250
|
-
end
|
251
|
-
end
|
252
174
|
end
|
253
|
-
|
254
|
-
def initialize_dup(other)
|
255
|
-
super
|
256
|
-
ensure_proper_type
|
257
|
-
end
|
258
|
-
|
259
|
-
private
|
260
|
-
|
261
|
-
def initialize_internals_callback
|
262
|
-
super
|
263
|
-
ensure_proper_type
|
264
|
-
end
|
265
|
-
|
266
|
-
# Sets the attribute used for single table inheritance to this class name if this is not the
|
267
|
-
# ActiveEntity::Base descendant.
|
268
|
-
# Considering the hierarchy Reply < Message < ActiveEntity::Base, this makes it possible to
|
269
|
-
# do Reply.new without having to set <tt>Reply[Reply.inheritance_attribute] = "Reply"</tt> yourself.
|
270
|
-
# No such attribute would be set for objects of the Message class in that example.
|
271
|
-
def ensure_proper_type
|
272
|
-
klass = self.class
|
273
|
-
if klass.finder_needs_type_condition?
|
274
|
-
_write_attribute(klass.inheritance_attribute, klass.sti_name)
|
275
|
-
end
|
276
|
-
end
|
277
175
|
end
|
278
176
|
end
|
@@ -30,7 +30,7 @@ module ActiveEntity
|
|
30
30
|
# user_path(user) # => "/users/Phusion"
|
31
31
|
def to_param
|
32
32
|
# We can't use alias_method here, because method 'id' optimizes itself on the fly.
|
33
|
-
id
|
33
|
+
id&.to_s # Be sure to stringify the id for routes
|
34
34
|
end
|
35
35
|
|
36
36
|
module ClassMethods
|
@@ -9,22 +9,10 @@ module ActiveEntity
|
|
9
9
|
included do
|
10
10
|
delegate :type_for_attribute, to: :class
|
11
11
|
|
12
|
-
self.inheritance_attribute = "type"
|
13
|
-
|
14
12
|
initialize_load_schema_monitor
|
15
13
|
end
|
16
14
|
|
17
15
|
module ClassMethods
|
18
|
-
def inheritance_attribute
|
19
|
-
(@inheritance_attribute ||= nil) || superclass.inheritance_attribute
|
20
|
-
end
|
21
|
-
|
22
|
-
# Sets the value of inheritance_attribute
|
23
|
-
def inheritance_attribute=(value)
|
24
|
-
@inheritance_attribute = value.to_s
|
25
|
-
@explicit_inheritance_attribute = true
|
26
|
-
end
|
27
|
-
|
28
16
|
def attributes_builder # :nodoc:
|
29
17
|
unless defined?(@attributes_builder) && @attributes_builder
|
30
18
|
defaults = _default_attributes
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require "active_support/core_ext/hash/except"
|
4
4
|
require "active_support/core_ext/module/redefine_method"
|
5
|
-
require "active_support/core_ext/object/try"
|
6
5
|
require "active_support/core_ext/hash/indifferent_access"
|
7
6
|
|
8
7
|
module ActiveEntity
|
@@ -289,7 +288,7 @@ module ActiveEntity
|
|
289
288
|
# [:allow_destroy]
|
290
289
|
# If true, destroys any members from the attributes hash with a
|
291
290
|
# <tt>_destroy</tt> key and a value that evaluates to +true+
|
292
|
-
# (
|
291
|
+
# (e.g. 1, '1', true, or 'true'). This option is off by default.
|
293
292
|
# [:reject_if]
|
294
293
|
# Allows you to specify a Proc or a Symbol pointing to a method
|
295
294
|
# that checks whether a record should be built for a certain attribute
|
@@ -465,10 +464,10 @@ module ActiveEntity
|
|
465
464
|
if attributes_collection.is_a? Hash
|
466
465
|
keys = attributes_collection.keys
|
467
466
|
attributes_collection = if keys.include?("id") || keys.include?(:id)
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
467
|
+
[attributes_collection]
|
468
|
+
else
|
469
|
+
attributes_collection.values
|
470
|
+
end
|
472
471
|
end
|
473
472
|
|
474
473
|
association = association(association_name)
|
@@ -551,11 +550,5 @@ module ActiveEntity
|
|
551
550
|
def allow_destroy?(association_name)
|
552
551
|
nested_attributes_options[association_name][:allow_destroy]
|
553
552
|
end
|
554
|
-
|
555
|
-
def raise_nested_attributes_record_not_found!(association_name, record_id)
|
556
|
-
model = self.class._reflect_on_association(association_name).klass.name
|
557
|
-
raise RecordNotFound.new("Couldn't find #{model} with ID=#{record_id} for #{self.class.name} with ID=#{id}",
|
558
|
-
model, "id", record_id)
|
559
|
-
end
|
560
553
|
end
|
561
554
|
end
|
@@ -2,15 +2,75 @@
|
|
2
2
|
|
3
3
|
require "active_entity"
|
4
4
|
require "rails"
|
5
|
+
require "active_support/core_ext/object/try"
|
5
6
|
require "active_model/railtie"
|
6
7
|
|
8
|
+
# For now, action_controller must always be present with
|
9
|
+
# Rails, so let's make sure that it gets required before
|
10
|
+
# here. This is needed for correctly setting up the middleware.
|
11
|
+
# In the future, this might become an optional require.
|
12
|
+
require "action_controller/railtie"
|
13
|
+
|
7
14
|
module ActiveEntity
|
8
15
|
# = Active Entity Railtie
|
9
16
|
class Railtie < Rails::Railtie # :nodoc:
|
17
|
+
config.active_entity = ActiveSupport::OrderedOptions.new
|
18
|
+
|
10
19
|
config.eager_load_namespaces << ActiveEntity
|
11
20
|
|
21
|
+
# When loading console, force ActiveEntity::Base to be loaded
|
22
|
+
# to avoid cross references when loading a constant for the
|
23
|
+
# first time. Also, make it output to STDERR.
|
24
|
+
console do |_app|
|
25
|
+
require "active_entity/base"
|
26
|
+
unless ActiveSupport::Logger.logger_outputs_to?(Rails.logger, STDERR, STDOUT)
|
27
|
+
console = ActiveSupport::Logger.new(STDERR)
|
28
|
+
Rails.logger.extend ActiveSupport::Logger.broadcast console
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
12
32
|
runner do
|
13
|
-
require "
|
33
|
+
require "active_entity/base"
|
34
|
+
end
|
35
|
+
|
36
|
+
initializer "active_entity.initialize_timezone" do
|
37
|
+
ActiveSupport.on_load(:active_entity) do
|
38
|
+
self.time_zone_aware_attributes = true
|
39
|
+
self.default_timezone = :utc
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
initializer "active_entity.logger" do
|
44
|
+
ActiveSupport.on_load(:active_entity) { self.logger ||= ::Rails.logger }
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
initializer "active_entity.define_attribute_methods" do |app|
|
49
|
+
config.after_initialize do
|
50
|
+
ActiveSupport.on_load(:active_entity) do
|
51
|
+
if app.config.eager_load
|
52
|
+
descendants.each do |model|
|
53
|
+
model.define_attribute_methods
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
initializer "active_entity.set_configs" do |app|
|
61
|
+
ActiveSupport.on_load(:active_entity) do
|
62
|
+
configs = app.config.active_entity
|
63
|
+
|
64
|
+
configs.each do |k, v|
|
65
|
+
send "#{k}=", v
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
initializer "active_entity.set_filter_attributes" do
|
71
|
+
ActiveSupport.on_load(:active_entity) do
|
72
|
+
self.filter_attributes += Rails.application.config.filter_parameters
|
73
|
+
end
|
14
74
|
end
|
15
75
|
end
|
16
76
|
end
|
@@ -16,7 +16,7 @@ module ActiveEntity
|
|
16
16
|
@_attr_readonly_enabled = true
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
19
|
+
def without_attr_readonly
|
20
20
|
return unless block_given?
|
21
21
|
|
22
22
|
disable_attr_readonly!
|
@@ -31,6 +31,10 @@ module ActiveEntity
|
|
31
31
|
end
|
32
32
|
alias attr_readonly_enabled? _attr_readonly_enabled
|
33
33
|
|
34
|
+
def readonly_attribute?(name)
|
35
|
+
self.class.readonly_attribute?(name)
|
36
|
+
end
|
37
|
+
|
34
38
|
module ClassMethods
|
35
39
|
# Attributes listed as readonly will be used to create a new record but update operations will
|
36
40
|
# ignore these fields.
|
@@ -42,6 +46,10 @@ module ActiveEntity
|
|
42
46
|
def readonly_attributes
|
43
47
|
_attr_readonly
|
44
48
|
end
|
49
|
+
|
50
|
+
def readonly_attribute?(name) # :nodoc:
|
51
|
+
_attr_readonly.include?(name)
|
52
|
+
end
|
45
53
|
end
|
46
54
|
end
|
47
55
|
end
|