Class: DataMapper::Property
- Inherits:
-
Object
- Object
- DataMapper::Property
- Extended by:
- Deprecate, Equalizer
- Includes:
- Assertions, Subject
- Defined in:
- lib/dm-core/property.rb,
lib/dm-core/property/text.rb,
lib/dm-core/property/time.rb,
lib/dm-core/property/date.rb,
lib/dm-core/property/float.rb,
lib/dm-core/property/class.rb,
lib/dm-core/property/string.rb,
lib/dm-core/property/serial.rb,
lib/dm-core/property/binary.rb,
lib/dm-core/property/object.rb,
lib/dm-core/property/lookup.rb,
lib/dm-core/property/numeric.rb,
lib/dm-core/property/boolean.rb,
lib/dm-core/property/integer.rb,
lib/dm-core/property/decimal.rb,
lib/dm-core/property/date_time.rb,
lib/dm-core/property/discriminator.rb,
lib/dm-core/property/invalid_value_error.rb
Overview
Properties
Properties for a model are not derived from a database structure, but instead explicitly declared inside your model class definitions. These properties then map (or, if using automigrate, generate) fields in your repository/database.
If you are coming to DataMapper from another ORM framework, such as ActiveRecord, this may be a fundamental difference in thinking to you. However, there are several advantages to defining your properties in your models:
-
information about your model is centralized in one place: rather than having to dig out migrations, xml or other configuration files.
-
use of mixins can be applied to model properties: better code reuse
-
having information centralized in your models, encourages you and the developers on your team to take a model-centric view of development.
-
it provides the ability to use Ruby's access control functions.
-
and, because DataMapper only cares about properties explicitly defined in your models, DataMapper plays well with legacy databases, and shares databases easily with other applications.
Declaring Properties
Inside your class, you call the property method for each property you want to add. The only two required arguments are the name and type, everything else is optional.
class Post
include DataMapper::Resource
property :title, String, :required => true # Cannot be null
property :publish, Boolean, :default => false # Default value for new records is false
end
By default, DataMapper supports the following primitive (Ruby) types also called core properties:
-
Boolean
-
Class (datastore primitive is the same as String. Used for Inheritance)
-
Date
-
DateTime
-
Decimal
-
Float
-
Integer
-
Object (marshalled out during serialization)
-
String (default length is 50)
-
Text (limit of 65k characters by default)
-
Time
Limiting Access
Property access control is uses the same terminology Ruby does. Properties are public by default, but can also be declared private or protected as needed (via the :accessor option).
class Post
include DataMapper::Resource
property :title, String, :accessor => :private # Both reader and writer are private
property :body, Text, :accessor => :protected # Both reader and writer are protected
end
Access control is also analogous to Ruby attribute readers and writers, and can be declared using :reader and :writer, in addition to :accessor.
class Post
include DataMapper::Resource
property :title, String, :writer => :private # Only writer is private
property :tags, String, :reader => :protected # Only reader is protected
end
Overriding Accessors
The reader/writer for any property can be overridden in the same manner that Ruby attr readers/writers can be. After the property is defined, just add your custom reader or writer:
class Post
include DataMapper::Resource
property :title, String
def title=(new_title)
raise ArgumentError if new_title != 'Lee is l337'
super(new_title)
end
end
Calling super ensures that any validators defined for the property are kept active.
Lazy Loading
By default, some properties are not loaded when an object is fetched in DataMapper. These lazily loaded properties are fetched on demand when their accessor is called for the first time (as it is often unnecessary to instantiate -every- property -every- time an object is loaded). For instance, DataMapper::Property::Text fields are lazy loading by default, although you can over-ride this behavior if you wish:
Example:
class Post
include DataMapper::Resource
property :title, String # Loads normally
property :body, Text # Is lazily loaded by default
end
If you want to over-ride the lazy loading on any field you can set it to a context or false to disable it with the :lazy option. Contexts allow multiple lazy properties to be loaded at one time. If you set :lazy to true, it is placed in the :default context
class Post
include DataMapper::Resource
property :title, String # Loads normally
property :body, Text, :lazy => false # The default is now over-ridden
property :comment, String, :lazy => [ :detailed ] # Loads in the :detailed context
property :author, String, :lazy => [ :summary, :detailed ] # Loads in :summary & :detailed context
end
Delaying the request for lazy-loaded attributes even applies to objects accessed through associations. In a sense, DataMapper anticipates that you will likely be iterating over objects in associations and rolls all of the load commands for lazy-loaded properties into one request from the database.
Example:
Widget.get(1).components
# loads when the post object is pulled from database, by default
Widget.get(1).components.first.body
# loads the values for the body property on all objects in the
# association, rather than just this one.
Widget.get(1).components.first.comment
# loads both comment and author for all objects in the association
# since they are both in the :detailed context
Keys
Properties can be declared as primary or natural keys on a table. You should a property as the primary key of the table:
Examples:
property :id, Serial # auto-incrementing key
property :legacy_pk, String, :key => true # 'natural' key
This is roughly equivalent to ActiveRecord's set_primary_key, though non-integer data types may be used, thus DataMapper supports natural keys. When a property is declared as a natural key, accessing the object using the indexer syntax Class[key] remains valid.
User.get(1)
# when :id is the primary key on the users table
User.get('bill')
# when :name is the primary (natural) key on the users table
Indices
You can add indices for your properties by using the :index option. If you use true as the option value, the index will be automatically named. If you want to name the index yourself, use a symbol as the value.
property :last_name, String, :index => true
property :first_name, String, :index => :name
You can create multi-column composite indices by using the same symbol in all the columns belonging to the index. The columns will appear in the index in the order they are declared.
property :last_name, String, :index => :name
property :first_name, String, :index => :name
# => index on (last_name, first_name)
If you want to make the indices unique, use :unique_index instead of :index
Inferred Validations
If you require the dm-validations plugin, auto-validations will automatically be mixed-in in to your model classes: validation rules that are inferred when properties are declared with specific column restrictions.
class Post
include DataMapper::Resource
property :title, String, :length => 250, :min => 0, :max => 250
# => infers 'validates_length :title'
property :title, String, :required => true
# => infers 'validates_present :title'
property :email, String, :format => :email_address
# => infers 'validates_format :email, :with => :email_address'
property :title, String, :length => 255, :required => true
# => infers both 'validates_length' as well as 'validates_present'
# better: property :title, String, :length => 1..255
end
This functionality is available with the dm-validations gem. For more information about validations, check the documentation for dm-validations.
Default Values
To set a default for a property, use the :default key. The property will be set to the value associated with that key the first time it is accessed, or when the resource is saved if it hasn't been set with another value already. This value can be a static value, such as 'hello' but it can also be a proc that will be evaluated when the property is read before its value has been set. The property is set to the return of the proc. The proc is passed two values, the resource the property is being set for and the property itself.
property :display_name, String, :default => lambda { |resource, property| resource.login }
Word of warning. Don't try to read the value of the property you're setting the default for in the proc. An infinite loop will ensue.
Embedded Values (not implemented yet)
As an alternative to extraneous has_one relationships, consider using an EmbeddedValue.
Property options reference
:accessor if false, neither reader nor writer methods are
created for this property
:reader if false, reader method is not created for this property
:writer if false, writer method is not created for this property
:lazy if true, property value is only loaded when on first read
if false, property value is always loaded
if a symbol, property value is loaded with other properties
in the same group
:default default value of this property
:allow_nil if true, property may have a nil value on save
:key name of the key associated with this property.
:field field in the data-store which the property corresponds to
:length string field length
:format format for autovalidation. Use with dm-validations plugin.
:index if true, index is created for the property. If a Symbol, index
is named after Symbol value instead of being based on property name.
:unique_index true specifies that index on this property should be unique
:auto_validation if true, automatic validation is performed on the property
:validates validation context. Use together with dm-validations.
:unique if true, property column is unique. Properties of type Serial
are unique by default.
:precision Indicates the number of significant digits. Usually only makes sense
for float type properties. Must be >= scale option value. Default is 10.
:scale The number of significant digits to the right of the decimal point.
Only makes sense for float type properties. Must be > 0.
Default is nil for Float type and 10 for BigDecimal
Overriding default Property options
There is the ability to reconfigure a Property and it's subclasses by explicitly setting a value in the Property, eg:
# set all String properties to have a default length of 255
DataMapper::Property::String.length(255)
# set all Boolean properties to not allow nil (force true or false)
DataMapper::Property::Boolean.allow_nil(false)
# set all properties to be required by default
DataMapper::Property.required(true)
# turn off auto-validation for all properties by default
DataMapper::Property.auto_validation(false)
# set all mutator methods to be private by default
DataMapper::Property.writer(:private)
Please note that this has no effect when a subclass has explicitly defined it's own option. For example, setting the String length to 255 will not affect the Text property even though it inherits from String, because it sets it's own default length to 65535.
Misc. Notes
-
Properties declared as strings will default to a length of 50, rather than 255 (typical max varchar column size). To overload the default, pass :length => 255 or :length => 0..255. Since DataMapper does not introspect for properties, this means that legacy database tables may need their String columns defined with a :length so that DM does not apply an un-needed length validation, or allow overflow.
-
You may declare a Property with the data-type of Class. see SingleTableInheritance for more on how to use Class columns.
Direct Known Subclasses
Defined Under Namespace
Modules: Lookup Classes: Binary, Boolean, Class, Date, DateTime, Decimal, Discriminator, Float, Integer, InvalidValueError, Numeric, Object, Serial, String, Text, Time
Constant Summary
- PRIMITIVES =
[ TrueClass, ::String, ::Float, ::Integer, ::BigDecimal, ::DateTime, ::Date, ::Time, ::Class ].to_set.freeze
- OPTIONS =
[ :load_as, :dump_as, :coercion_method, :accessor, :reader, :writer, :lazy, :default, :key, :field, :index, :unique_index, :unique, :allow_nil, :allow_blank, :required ]
- VISIBILITY_OPTIONS =
Possible :visibility option values
[ :public, :protected, :private ].to_set.freeze
- INVALID_NAMES =
Invalid property names
(Resource.instance_methods + Resource.private_instance_methods + Query::OPTIONS.to_a ).map { |name| name.to_s }
Instance Attribute Summary (collapse)
-
- (Object) allow_blank
readonly
Returns the value of attribute allow_blank.
-
- (Object) allow_nil
readonly
Returns the value of attribute allow_nil.
-
- (Object) coercion_method
readonly
Returns the value of attribute coercion_method.
-
- (Object) default
readonly
Returns the value of attribute default.
-
- (Object) dump_as
(also: #dump_class)
readonly
Returns the value of attribute dump_as.
-
- (Boolean, ...) index
readonly
Returns index name if property has index.
-
- (Object) instance_variable_name
readonly
Returns the value of attribute instance_variable_name.
-
- (Object) load_as
(also: #load_class)
readonly
Returns the value of attribute load_as.
-
- (Object) model
readonly
Returns the value of attribute model.
-
- (Object) name
readonly
Returns the value of attribute name.
-
- (Object) options
readonly
Returns the value of attribute options.
-
- (Object) reader_visibility
readonly
Returns the value of attribute reader_visibility.
-
- (Object) repository_name
readonly
Returns the value of attribute repository_name.
-
- (Object) required
readonly
Returns the value of attribute required.
-
- (Boolean, ...) unique_index
readonly
Returns true if property has unique index.
-
- (Object) writer_visibility
readonly
Returns the value of attribute writer_visibility.
Class Method Summary (collapse)
- + (Object) accept_options(*args)
- + (Object) accepted_options
- + (Object) demodulized_names private
- + (Object) descendants
- + (Object) determine_class(type)
- + (Object) find_class(name)
- + (Object) inherited(descendant) private
- + (Object) nullable(*args) private
-
+ (Hash) options
Gives all the options set on this property.
- + (Object) primitive(*args)
Instance Method Summary (collapse)
-
- (Boolean) allow_blank?
Returns whether or not the property can be a blank value.
-
- (Boolean) allow_nil?
Returns whether or not the property can accept 'nil' as it's value.
- - (Object) assert_valid_options(options) protected private
-
- (Boolean) assert_valid_value(value)
Asserts value is valid.
-
- (Object) bind
A hook to allow properties to extend or modify the model it's bound to.
-
- (undefined) determine_visibility
protected
private
Assert given visibility value is supported.
-
- (String) field(repository_name = nil)
Supplies the field in the data-store which the property corresponds to.
-
- (Object) get(resource)
private
Standardized reader method for the property.
-
- (Object) get!(resource)
private
Fetch the ivar value in the resource.
-
- (Property) initialize(model, name, options = {})
constructor
protected
A new instance of Property.
-
- (String) inspect
Returns a concise string representation of the property instance.
-
- (Boolean) key?
Returns whether or not the property is a key or a part of a key.
-
- (Boolean) lazy?
Returns whether or not the property is to be lazy-loaded.
-
- (Object) lazy_load(resource)
private
Loads lazy columns when get or set is called.
- - (Object) lazy_load_properties private
-
- (Boolean) loaded?(resource)
private
Check if the attribute corresponding to the property is loaded.
- - (Object) primitive
-
- (Boolean) primitive?(value)
Test a value to see if it matches the primitive type.
- - (Object) properties private
-
- (Boolean) required?
Returns whether or not the property must be non-nil and non-blank.
-
- (Boolean) serial?
Returns whether or not the property is “serial” (auto-incrementing).
-
- (Object) set(resource, value)
private
Provides a standardized setter method for the property.
-
- (Object) set!(resource, value)
private
Set the ivar value in the resource.
- - (Object) typecast(value)
-
- (Boolean) unique?
Returns true if property is unique.
-
- (Boolean) valid?(value, negated = false)
Test the value to see if it is a valid value for this Property.
- - (Boolean) value_dumped?(value)
- - (Boolean) value_loaded?(value)
Methods included from Deprecate
Methods included from Equalizer
Methods included from Subject
Methods included from Assertions
Constructor Details
- (Property) initialize(model, name, options = {}) (protected)
A new instance of Property
759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 |
# File 'lib/dm-core/property.rb', line 759 def initialize(model, name, = {}) = .to_hash.dup if INVALID_NAMES.include?(name.to_s) || (kind_of?(Boolean) && INVALID_NAMES.include?("#{name}?")) raise ArgumentError, "+name+ was #{name.inspect}, which cannot be used as a property name since it collides with an existing method or a query option" end () = self.class. @repository_name = model.repository_name @model = model @name = name.to_s.chomp('?').to_sym @options = .merge().freeze @instance_variable_name = "@#{@name}".freeze @coercion_method = @options.fetch(:coercion_method) @load_as = self.class.load_as @dump_as = self.class.dump_as @field = @options[:field].freeze unless @options[:field].nil? @default = @options[:default] @serial = @options.fetch(:serial, false) @key = @options.fetch(:key, @serial) @unique = @options.fetch(:unique, @key ? :key : false) @required = @options.fetch(:required, @key) @allow_nil = @options.fetch(:allow_nil, !@required) @allow_blank = @options.fetch(:allow_blank, !@required) @index = @options.fetch(:index, false) @unique_index = @options.fetch(:unique_index, @unique) @lazy = @options.fetch(:lazy, false) && !@key determine_visibility bind end |
Instance Attribute Details
- (Object) allow_blank (readonly)
Returns the value of attribute allow_blank
338 339 340 |
# File 'lib/dm-core/property.rb', line 338 def allow_blank @allow_blank end |
- (Object) allow_nil (readonly)
Returns the value of attribute allow_nil
338 339 340 |
# File 'lib/dm-core/property.rb', line 338 def allow_nil @allow_nil end |
- (Object) coercion_method (readonly)
Returns the value of attribute coercion_method
338 339 340 |
# File 'lib/dm-core/property.rb', line 338 def coercion_method @coercion_method end |
- (Object) default (readonly)
Returns the value of attribute default
338 339 340 |
# File 'lib/dm-core/property.rb', line 338 def default @default end |
- (Object) dump_as (readonly) Also known as: dump_class
Returns the value of attribute dump_as
338 339 340 |
# File 'lib/dm-core/property.rb', line 338 def dump_as @dump_as end |
- (Boolean, ...) index (readonly)
Returns index name if property has index.
504 505 506 |
# File 'lib/dm-core/property.rb', line 504 def index @index end |
- (Object) instance_variable_name (readonly)
Returns the value of attribute instance_variable_name
338 339 340 |
# File 'lib/dm-core/property.rb', line 338 def instance_variable_name @instance_variable_name end |
- (Object) load_as (readonly) Also known as: load_class
Returns the value of attribute load_as
338 339 340 |
# File 'lib/dm-core/property.rb', line 338 def load_as @load_as end |
- (Object) model (readonly)
Returns the value of attribute model
338 339 340 |
# File 'lib/dm-core/property.rb', line 338 def model @model end |
- (Object) name (readonly)
Returns the value of attribute name
338 339 340 |
# File 'lib/dm-core/property.rb', line 338 def name @name end |
- (Object) options (readonly)
Returns the value of attribute options
338 339 340 |
# File 'lib/dm-core/property.rb', line 338 def @options end |
- (Object) reader_visibility (readonly)
Returns the value of attribute reader_visibility
338 339 340 |
# File 'lib/dm-core/property.rb', line 338 def reader_visibility @reader_visibility end |
- (Object) repository_name (readonly)
Returns the value of attribute repository_name
338 339 340 |
# File 'lib/dm-core/property.rb', line 338 def repository_name @repository_name end |
- (Object) required (readonly)
Returns the value of attribute required
338 339 340 |
# File 'lib/dm-core/property.rb', line 338 def required @required end |
- (Boolean, ...) unique_index (readonly)
Returns true if property has unique index. Serial properties and keys are unique by default.
516 517 518 |
# File 'lib/dm-core/property.rb', line 516 def unique_index @unique_index end |
- (Object) writer_visibility (readonly)
Returns the value of attribute writer_visibility
338 339 340 |
# File 'lib/dm-core/property.rb', line 338 def writer_visibility @writer_visibility end |
Class Method Details
+ (Object) accept_options(*args)
413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 |
# File 'lib/dm-core/property.rb', line 413 def (*args) .concat(args) # create methods for each new option args.each do |property_option| class_eval <<-RUBY, __FILE__, __LINE__ + 1 def self.#{property_option}(value = Undefined) # def self.unique(value = Undefined) return @#{property_option} if value.equal?(Undefined) # return @unique if value.equal?(Undefined) descendants.each do |descendant| # descendants.each do |descendant| unless descendant.instance_variable_defined?(:@#{property_option}) # unless descendant.instance_variable_defined?(:@unique) descendant.#{property_option}(value) # descendant.unique(value) end # end end # end @#{property_option} = value # @unique = value end # end RUBY end descendants.each { |descendant| descendant..concat(args) } end |
+ (Object) accepted_options
408 409 410 |
# File 'lib/dm-core/property.rb', line 408 def @accepted_options ||= [] end |
+ (Object) demodulized_names
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
358 359 360 |
# File 'lib/dm-core/property.rb', line 358 def demodulized_names @demodulized_names ||= {} end |
+ (Object) descendants
370 371 372 |
# File 'lib/dm-core/property.rb', line 370 def descendants @descendants ||= DescendantSet.new end |
+ (Object) determine_class(type)
352 353 354 355 |
# File 'lib/dm-core/property.rb', line 352 def determine_class(type) return type if type < DataMapper::Property::Object find_class(DataMapper::Inflector.demodulize(type.name)) end |
+ (Object) find_class(name)
363 364 365 366 367 |
# File 'lib/dm-core/property.rb', line 363 def find_class(name) klass = demodulized_names[name] klass ||= const_get(name) if const_defined?(name) klass end |
+ (Object) inherited(descendant)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 |
# File 'lib/dm-core/property.rb', line 375 def inherited(descendant) # Descendants is a tree rooted in DataMapper::Property that tracks # inheritance. We pre-calculate each comparison value (demodulized # class name) to achieve a Hash[]-time lookup, rather than walk the # entire descendant tree and calculate names on-demand (expensive, # redundant). # # Since the algorithm relegates property class name lookups to a flat # namespace, we need to ensure properties defined outside of DM don't # override built-ins (Serial, String, etc) by merely defining a property # of a same name. We avoid this by only ever adding to the lookup # table. Given that DM loads its own property classes first, we can # assume that their names are "reserved" when added to the table. # # External property authors who want to provide "replacements" for # builtins (e.g. in a non-DM-supported adapter) should follow the # convention of wrapping those properties in a module, and include'ing # the module on the model class directly. This bypasses the DM-hooked # const_missing lookup that would normally check this table. descendants << descendant Property.demodulized_names[DataMapper::Inflector.demodulize(descendant.name)] ||= descendant # inherit accepted options descendant..concat() # inherit the option values .each { |key, value| descendant.send(key, value) } super end |
+ (Object) nullable(*args)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
435 436 437 438 |
# File 'lib/dm-core/property.rb', line 435 def nullable(*args) # :required is preferable to :allow_nil, but :nullable maps precisely to :allow_nil raise "#nullable is deprecated, use #required instead (#{caller.first})" end |
+ (Hash) options
Gives all the options set on this property
445 446 447 448 449 450 451 |
# File 'lib/dm-core/property.rb', line 445 def = {} .each do |name| [name] = send(name) if instance_variable_defined?("@#{name}") end end |
+ (Object) primitive(*args)
454 455 456 457 |
# File 'lib/dm-core/property.rb', line 454 def primitive(*args) warn "DataMapper::Property.primitive is deprecated, use .load_as instead (#{caller.first})" load_as(*args) end |
Instance Method Details
- (Boolean) allow_blank?
Returns whether or not the property can be a blank value
574 575 576 |
# File 'lib/dm-core/property.rb', line 574 def allow_blank? @allow_blank end |
- (Boolean) allow_nil?
Returns whether or not the property can accept 'nil' as it's value
564 565 566 |
# File 'lib/dm-core/property.rb', line 564 def allow_nil? @allow_nil end |
- (Object) assert_valid_options(options) (protected)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 |
# File 'lib/dm-core/property.rb', line 800 def () keys = .keys if (unknown_keys = keys - self.class.).any? raise ArgumentError, "options #{unknown_keys.map { |key| key.inspect }.join(' and ')} are unknown" end .each do |key, value| boolean_value = value == true || value == false case key when :field assert_kind_of "options[:#{key}]", value, ::String when :default if value.nil? raise ArgumentError, "options[:#{key}] must not be nil" end when :serial, :key, :allow_nil, :allow_blank, :required, :auto_validation unless boolean_value raise ArgumentError, "options[:#{key}] must be either true or false" end if key == :required && (keys.include?(:allow_nil) || keys.include?(:allow_blank)) raise ArgumentError, 'options[:required] cannot be mixed with :allow_nil or :allow_blank' end when :index, :unique_index, :unique, :lazy unless boolean_value || value.kind_of?(Symbol) || (value.kind_of?(Array) && value.any? && value.all? { |val| val.kind_of?(Symbol) }) raise ArgumentError, "options[:#{key}] must be either true, false, a Symbol or an Array of Symbols" end when :length assert_kind_of "options[:#{key}]", value, Range, ::Integer when :size, :precision, :scale assert_kind_of "options[:#{key}]", value, ::Integer when :reader, :writer, :accessor assert_kind_of "options[:#{key}]", value, Symbol unless VISIBILITY_OPTIONS.include?(value) raise ArgumentError, "options[:#{key}] must be #{VISIBILITY_OPTIONS.join(' or ')}" end end end end |
- (Boolean) assert_valid_value(value)
Asserts value is valid
710 711 712 713 714 715 |
# File 'lib/dm-core/property.rb', line 710 def assert_valid_value(value) unless valid?(value) raise Property::InvalidValueError.new(self,value) end true end |
- (Object) bind
A hook to allow properties to extend or modify the model it's bound to. Implementations are not supposed to modify the state of the property class, and should produce no side-effects on the property instance.
465 466 467 |
# File 'lib/dm-core/property.rb', line 465 def bind # no op end |
- (undefined) determine_visibility (protected)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Assert given visibility value is supported.
Will raise ArgumentError if this Property's reader and writer visibilities are not included in VISIBILITY_OPTIONS.
859 860 861 862 863 864 |
# File 'lib/dm-core/property.rb', line 859 def determine_visibility default_accessor = @options.fetch(:accessor, :public) @reader_visibility = @options.fetch(:reader, default_accessor) @writer_visibility = @options.fetch(:writer, default_accessor) end |
- (String) field(repository_name = nil)
Supplies the field in the data-store which the property corresponds to
474 475 476 477 478 479 480 481 482 |
# File 'lib/dm-core/property.rb', line 474 def field(repository_name = nil) if repository_name raise "Passing in +repository_name+ to #{self.class}#field is deprecated (#{caller.first})" end # defer setting the field with the adapter specific naming # conventions until after the adapter has been setup @field ||= model.field_naming_convention(self.repository_name).call(self).freeze end |
- (Object) get(resource)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Standardized reader method for the property
589 590 591 |
# File 'lib/dm-core/property.rb', line 589 def get(resource) get!(resource) end |
- (Object) get!(resource)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Fetch the ivar value in the resource
602 603 604 |
# File 'lib/dm-core/property.rb', line 602 def get!(resource) resource.instance_variable_get(instance_variable_name) end |
- (String) inspect
Returns a concise string representation of the property instance.
723 724 725 |
# File 'lib/dm-core/property.rb', line 723 def inspect "#<#{self.class.name} @model=#{model.inspect} @name=#{name.inspect}>" end |
- (Boolean) key?
Returns whether or not the property is a key or a part of a key
534 535 536 |
# File 'lib/dm-core/property.rb', line 534 def key? @key end |
- (Boolean) lazy?
Returns whether or not the property is to be lazy-loaded
524 525 526 |
# File 'lib/dm-core/property.rb', line 524 def lazy? @lazy end |
- (Object) lazy_load(resource)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Loads lazy columns when get or set is called.
657 658 659 660 |
# File 'lib/dm-core/property.rb', line 657 def lazy_load(resource) return if loaded?(resource) resource.__send__(:lazy_load, lazy_load_properties) end |
- (Object) lazy_load_properties
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
663 664 665 666 667 668 669 |
# File 'lib/dm-core/property.rb', line 663 def lazy_load_properties @lazy_load_properties ||= begin properties = self.properties properties.in_context(lazy? ? [ self ] : properties.defaults) end end |
- (Boolean) loaded?(resource)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Check if the attribute corresponding to the property is loaded
647 648 649 |
# File 'lib/dm-core/property.rb', line 647 def loaded?(resource) resource.instance_variable_defined?(instance_variable_name) end |
- (Object) primitive
741 742 743 744 |
# File 'lib/dm-core/property.rb', line 741 def primitive warn "#primitive is deprecated, use #dump_as instead (#{caller.first})" dump_as end |
- (Boolean) primitive?(value)
Test a value to see if it matches the primitive type
736 737 738 739 |
# File 'lib/dm-core/property.rb', line 736 def primitive?(value) warn "#primitive? is deprecated, use #value_dumped? instead (#{caller.first})" value_dumped?(value) end |
- (Object) properties
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
672 673 674 |
# File 'lib/dm-core/property.rb', line 672 def properties @properties ||= model.properties(repository_name) end |
- (Boolean) required?
Returns whether or not the property must be non-nil and non-blank
554 555 556 |
# File 'lib/dm-core/property.rb', line 554 def required? @required end |
- (Boolean) serial?
Returns whether or not the property is “serial” (auto-incrementing)
544 545 546 |
# File 'lib/dm-core/property.rb', line 544 def serial? @serial end |
- (Object) set(resource, value)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Provides a standardized setter method for the property
619 620 621 |
# File 'lib/dm-core/property.rb', line 619 def set(resource, value) set!(resource, typecast(value)) end |
- (Object) set!(resource, value)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Set the ivar value in the resource
634 635 636 |
# File 'lib/dm-core/property.rb', line 634 def set!(resource, value) resource.instance_variable_set(instance_variable_name, value) end |
- (Object) typecast(value)
677 678 679 |
# File 'lib/dm-core/property.rb', line 677 def typecast(value) Virtus::Coercion[value.class].send(coercion_method, value) end |
- (Boolean) unique?
Returns true if property is unique. Serial properties and keys are unique by default.
491 492 493 |
# File 'lib/dm-core/property.rb', line 491 def unique? !!@unique end |
- (Boolean) valid?(value, negated = false)
Test the value to see if it is a valid value for this Property
690 691 692 693 694 695 696 697 698 |
# File 'lib/dm-core/property.rb', line 690 def valid?(value, negated = false) dumped_value = dump(value) if required? && dumped_value.nil? negated || false else value_dumped?(dumped_value) || (dumped_value.nil? && (allow_nil? || negated)) end end |
- (Boolean) value_dumped?(value)
747 748 749 |
# File 'lib/dm-core/property.rb', line 747 def value_dumped?(value) value.kind_of?(dump_as) end |
- (Boolean) value_loaded?(value)
752 753 754 |
# File 'lib/dm-core/property.rb', line 752 def value_loaded?(value) value.kind_of?(load_as) end |