Class: DataMapper::Property

### Home Classes Methods

### In Files

- lib/dm-core/property.rb
- lib/dm-core/property/binary.rb
- lib/dm-core/property/boolean.rb
- lib/dm-core/property/class.rb
- lib/dm-core/property/date.rb
- lib/dm-core/property/date_time.rb
- lib/dm-core/property/decimal.rb
- lib/dm-core/property/discriminator.rb
- lib/dm-core/property/float.rb
- lib/dm-core/property/integer.rb
- lib/dm-core/property/lookup.rb
- lib/dm-core/property/numeric.rb
- lib/dm-core/property/object.rb
- lib/dm-core/property/serial.rb
- lib/dm-core/property/string.rb
- lib/dm-core/property/text.rb
- lib/dm-core/property/time.rb
- lib/dm-core/property/typecast/numeric.rb
- lib/dm-core/property/typecast/time.rb

### Parent

Object

### Namespace

- MODULE DataMapper::Property::Lookup
- MODULE DataMapper::Property::PassThroughLoadDump
- MODULE DataMapper::Property::Typecast
- CLASS DataMapper::Property::Binary
- CLASS DataMapper::Property::Boolean
- CLASS DataMapper::Property::Class
- CLASS DataMapper::Property::Date
- CLASS DataMapper::Property::DateTime
- CLASS DataMapper::Property::Decimal
- CLASS DataMapper::Property::Discriminator
- CLASS DataMapper::Property::Float
- CLASS DataMapper::Property::Integer
- CLASS DataMapper::Property::Numeric
- CLASS DataMapper::Property::Object
- CLASS DataMapper::Property::Serial
- CLASS DataMapper::Property::String
- CLASS DataMapper::Property::Text
- CLASS DataMapper::Property::Time

### Methods

- ::accept_options
- ::accepted_options
- ::demodulized_names
- ::descendants
- ::determine_class
- ::find_class
- ::inherited
- ::new
- ::nullable
- ::options
- #allow_blank?
- #allow_nil?
- #assert_valid_options
- #bind
- #determine_visibility
- #field
- #get
- #get!
- #inspect
- #key?
- #lazy?
- #lazy_load
- #lazy_load_properties
- #loaded?
- #primitive?
- #properties
- #required?
- #serial?
- #set
- #set!
- #typecast
- #unique?
- #valid?

### Included Modules

- DataMapper::Assertions
- DataMapper::Subject

### Files

- LICENSE
- README.rdoc

### Class/Module Index

Quicksearch

- DataMapper
- DataMapper::Adapters
- DataMapper::Adapters::AbstractAdapter
- DataMapper::Adapters::InMemoryAdapter
- DataMapper::Assertions
- DataMapper::Associations
- DataMapper::Associations::ManyToMany
- DataMapper::Associations::ManyToMany::Collection
- DataMapper::Associations::ManyToMany::Relationship
- DataMapper::Associations::ManyToOne
- DataMapper::Associations::ManyToOne::Relationship
- DataMapper::Associations::OneToMany
- DataMapper::Associations::OneToMany::Collection
- DataMapper::Associations::OneToMany::Relationship
- DataMapper::Associations::OneToOne
- DataMapper::Associations::OneToOne::Relationship
- DataMapper::Associations::Relationship
- DataMapper::Chainable
- DataMapper::Collection
- DataMapper::Deprecate
- DataMapper::DescendantSet
- DataMapper::Equalizer
- DataMapper::Ext
- DataMapper::Ext::Array
- DataMapper::Ext::Hash
- DataMapper::Ext::Module
- DataMapper::Ext::Object
- DataMapper::Ext::String
- DataMapper::Hook
- DataMapper::Hook::ClassMethods
- DataMapper::IdentityMap
- DataMapper::ImmutableDeletedError
- DataMapper::ImmutableError
- DataMapper::IncompleteModelError
- DataMapper::Inflector
- DataMapper::Inflector::Inflections
- DataMapper::LocalObjectSpace
- DataMapper::Logger
- DataMapper::Mash
- DataMapper::Model
- DataMapper::Model::Hook
- DataMapper::Model::Hook::MethodCommand
- DataMapper::Model::Hook::Methods
- DataMapper::Model::Hook::ProcCommand
- DataMapper::Model::Is
- DataMapper::Model::Property
- DataMapper::Model::Relationship
- DataMapper::Model::Scope
- DataMapper::NamingConventions
- DataMapper::NamingConventions::Field
- DataMapper::NamingConventions::Field::Underscored
- DataMapper::NamingConventions::Field::UnderscoredAndPluralized
- DataMapper::NamingConventions::Field::UnderscoredAndPluralizedWithoutModule
- DataMapper::NamingConventions::Field::Yaml
- DataMapper::NamingConventions::Resource
- DataMapper::NamingConventions::Resource::Underscored
- DataMapper::NamingConventions::Resource::UnderscoredAndPluralized
- DataMapper::NamingConventions::Resource::UnderscoredAndPluralizedWithoutLeadingModule
- DataMapper::NamingConventions::Resource::UnderscoredAndPluralizedWithoutModule
- DataMapper::NamingConventions::Resource::Yaml
- DataMapper::ObjectNotFoundError
- DataMapper::OrderedSet
- DataMapper::OrderedSet::Cache
- DataMapper::OrderedSet::Cache::API
- DataMapper::PersistenceError
- DataMapper::PluginNotFoundError
- DataMapper::Property
- DataMapper::Property::Binary
- DataMapper::Property::Boolean
- DataMapper::Property::Class
- DataMapper::Property::Date
- DataMapper::Property::DateTime
- DataMapper::Property::Decimal
- DataMapper::Property::Discriminator
- DataMapper::Property::Discriminator::Model
- DataMapper::Property::Float
- DataMapper::Property::Integer
- DataMapper::Property::Lookup
- DataMapper::Property::Numeric
- DataMapper::Property::Object
- DataMapper::Property::PassThroughLoadDump
- DataMapper::Property::Serial
- DataMapper::Property::String
- DataMapper::Property::Text
- DataMapper::Property::Time
- DataMapper::Property::Typecast
- DataMapper::Property::Typecast::Numeric
- DataMapper::Property::Typecast::Time
- DataMapper::PropertySet
- DataMapper::Query
- DataMapper::Query::Conditions
- DataMapper::Query::Conditions::AbstractComparison
- DataMapper::Query::Conditions::AbstractOperation
- DataMapper::Query::Conditions::AndOperation
- DataMapper::Query::Conditions::Comparison
- DataMapper::Query::Conditions::EqualToComparison
- DataMapper::Query::Conditions::FlattenOperation
- DataMapper::Query::Conditions::GreaterThanComparison
- DataMapper::Query::Conditions::GreaterThanOrEqualToComparison
- DataMapper::Query::Conditions::InclusionComparison
- DataMapper::Query::Conditions::LessThanComparison
- DataMapper::Query::Conditions::LessThanOrEqualToComparison
- DataMapper::Query::Conditions::LikeComparison
- DataMapper::Query::Conditions::NotOperation
- DataMapper::Query::Conditions::NullOperation
- DataMapper::Query::Conditions::Operation
- DataMapper::Query::Conditions::OrOperation
- DataMapper::Query::Conditions::RegexpComparison
- DataMapper::Query::Conditions::RelationshipHandler
- DataMapper::Query::Direction
- DataMapper::Query::Operator
- DataMapper::Query::Path
- DataMapper::Query::Sort
- DataMapper::RelationshipSet
- DataMapper::Repository
- DataMapper::RepositoryNotSetupError
- DataMapper::Resource
- DataMapper::Resource::PersistenceState
- DataMapper::Resource::PersistenceState::Clean
- DataMapper::Resource::PersistenceState::Deleted
- DataMapper::Resource::PersistenceState::Dirty
- DataMapper::Resource::PersistenceState::Immutable
- DataMapper::Resource::PersistenceState::Persisted
- DataMapper::Resource::PersistenceState::Transient
- DataMapper::SaveFailureError
- DataMapper::Spec
- DataMapper::Spec::Adapters
- DataMapper::Spec::Adapters::Adapter
- DataMapper::Spec::Adapters::Helpers
- DataMapper::Spec::Adapters::InMemoryAdapter
- DataMapper::Spec::CollectionHelpers
- DataMapper::Spec::CollectionHelpers::GroupMethods
- DataMapper::Spec::Helpers
- DataMapper::Spec::PendingHelpers
- DataMapper::Subject
- DataMapper::SubjectSet
- DataMapper::SubjectSet::NameCache
- DataMapper::Undefined
- DataMapper::UnknownRelationshipError
- DataMapper::UnsavedParentError
- DataMapper::UpdateConflictError
- Blog
- Blog::Article
- ChildSubType
- CounterAdapter
- Heffalump
- Kernel
- LazyArray
- Object
- OtherComparison
- Pathname
- SubType
- Symbol

No matching classes.

# DataMapper::Property

# 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.

### Constants

INVALID_NAMES

  Invalid property names

OPTIONS
PRIMITIVES
VISIBILITY_OPTIONS

  Possible :visibility option values

### Attributes

allow_blank[R]
allow_nil[R]
default[R]
index[R]

Returns index name if property has index.

@return [Boolean, Symbol, Array]

    returns true if property is indexed by itself
    returns a Symbol if the property is indexed with other properties
    returns an Array if the property belongs to multiple indexes
    returns false if the property does not belong to any indexes

@api public

instance_variable_name[R]
model[R]
name[R]
options[R]
primitive[R]
reader_visibility[R]
repository_name[R]
required[R]
unique_index[R]

Returns true if property has unique index. Serial properties and keys are unique by default.

@return [Boolean, Symbol, Array]

    returns true if property is indexed by itself
    returns a Symbol if the property is indexed with other properties
    returns an Array if the property belongs to multiple indexes
    returns false if the property does not belong to any indexes

@api public

writer_visibility[R]

### Public Class Methods

accept_options(*args) click to toggle source

@api public

    # File lib/dm-core/property.rb, line 424
    def accept_options(*args)
      accepted_options.concat(args)

      # create methods for each new option
      args.each do |property_option|
        class_eval             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, __FILE__, __LINE__ + 1
      end

      descendants.each { |descendant| descendant.accepted_options.concat(args) }
    end

accepted_options() click to toggle source

@api public

    # File lib/dm-core/property.rb, line 419
    def accepted_options
      @accepted_options ||= []
    end

demodulized_names() click to toggle source

@api private

    # File lib/dm-core/property.rb, line 371
    def demodulized_names
      @demodulized_names ||= {}
    end

descendants() click to toggle source

@api public

    # File lib/dm-core/property.rb, line 383
    def descendants
      @descendants ||= DescendantSet.new
    end

determine_class(type) click to toggle source

@api semipublic

    # File lib/dm-core/property.rb, line 365
    def determine_class(type)
      return type if type < DataMapper::Property::Object
      find_class(DataMapper::Inflector.demodulize(type.name))
    end

find_class(name) click to toggle source

@api semipublic

    # File lib/dm-core/property.rb, line 376
    def find_class(name)
      klass   = demodulized_names[name]
      klass ||= const_get(name) if const_defined?(name)
      klass
    end

inherited(descendant) click to toggle source

@api private

    # File lib/dm-core/property.rb, line 388
    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.accepted_options.concat(accepted_options)

      # inherit the option values
      options.each { |key, value| descendant.send(key, value) }
    end

new(model, name, options = {}) click to toggle source

@api semipublic

    # File lib/dm-core/property.rb, line 737
    def initialize(model, name, options = {})
      options = options.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

      assert_valid_options(options)

      predefined_options = self.class.options

      @repository_name        = model.repository_name
      @model                  = model
      @name                   = name.to_s.chomp('?').to_sym
      @options                = predefined_options.merge(options).freeze
      @instance_variable_name = "@#{@name}".freeze

      @primitive = self.class.primitive
      @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

nullable(*args) click to toggle source

@api private

    # File lib/dm-core/property.rb, line 446
    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

options() click to toggle source

Gives all the options set on this property

@return [Hash] with all options and their values set on this property

@api public

    # File lib/dm-core/property.rb, line 456
    def options
      options = {}
      accepted_options.each do |name|
        options[name] = send(name) if instance_variable_defined?("@#{name}")
      end
      options
    end

### Public Instance Methods

allow_blank?() click to toggle source

Returns whether or not the property can be a blank value

@return [Boolean]

    whether or not the property can be blank

@api public

    # File lib/dm-core/property.rb, line 579
    def allow_blank?
      @allow_blank
    end

allow_nil?() click to toggle source

Returns whether or not the property can accept 'nil' as it's value

@return [Boolean]

    whether or not the property can accept 'nil'

@api public

    # File lib/dm-core/property.rb, line 569
    def allow_nil?
      @allow_nil
    end

bind() click to toggle source

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.

    # File lib/dm-core/property.rb, line 470
    def bind
      # no op
    end

field(repository_name = nil) click to toggle source

Supplies the field in the data-store which the property corresponds to

@return [String] name of field in data-store

@api semipublic

    # File lib/dm-core/property.rb, line 479
    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

get(resource) click to toggle source

Standardized reader method for the property

@param [Resource] resource

    model instance for which this property is to be loaded

@return [Object]

    the value of this property for the provided instance

@raise [ArgumentError] "`resource` should be a Resource, but was ...."

@api private

    # File lib/dm-core/property.rb, line 594
    def get(resource)
      get!(resource)
    end

get!(resource) click to toggle source

Fetch the ivar value in the resource

@param [Resource] resource

    model instance for which this property is to be unsafely loaded

@return [Object]

    current @ivar value of this property in +resource+

@api private

    # File lib/dm-core/property.rb, line 607
    def get!(resource)
      resource.instance_variable_get(instance_variable_name)
    end

inspect() click to toggle source

Returns a concise string representation of the property instance.

@return [String]

    Concise string representation of the property instance.

@api public

    # File lib/dm-core/property.rb, line 717
    def inspect
      "#<#{self.class.name} @model=#{model.inspect} @name=#{name.inspect}>"
    end

key?() click to toggle source

Returns whether or not the property is a key or a part of a key

@return [Boolean]

    true if the property is a key or a part of a key

@api public

    # File lib/dm-core/property.rb, line 539
    def key?
      @key
    end

lazy?() click to toggle source

Returns whether or not the property is to be lazy-loaded

@return [Boolean]

    true if the property is to be lazy-loaded

@api public

    # File lib/dm-core/property.rb, line 529
    def lazy?
      @lazy
    end

lazy_load(resource) click to toggle source

Loads lazy columns when get or set is called.

@param [Resource] resource

    model instance for which lazy loaded attribute are loaded

@api private

    # File lib/dm-core/property.rb, line 662
    def lazy_load(resource)
      return if loaded?(resource)
      resource.__send__(:lazy_load, lazy_load_properties)
    end

lazy_load_properties() click to toggle source

@api private

    # File lib/dm-core/property.rb, line 668
    def lazy_load_properties
      @lazy_load_properties ||=
        begin
          properties = self.properties
          properties.in_context(lazy? ? [ self ] : properties.defaults)
        end
    end

loaded?(resource) click to toggle source

Check if the attribute corresponding to the property is loaded

@param [Resource] resource

    model instance for which the attribute is to be tested

@return [Boolean]

    true if the attribute is loaded in the resource

@api private

    # File lib/dm-core/property.rb, line 652
    def loaded?(resource)
      resource.instance_variable_defined?(instance_variable_name)
    end

primitive?(value) click to toggle source

Test a value to see if it matches the primitive type

@param [Object] value

    value to test

@return [Boolean]

    true if the value is the correct type

@api semipublic

    # File lib/dm-core/property.rb, line 730
    def primitive?(value)
      value.kind_of?(primitive)
    end

properties() click to toggle source

@api private

    # File lib/dm-core/property.rb, line 677
    def properties
      @properties ||= model.properties(repository_name)
    end

required?() click to toggle source

Returns whether or not the property must be non-nil and non-blank

@return [Boolean]

    whether or not the property is required

@api public

    # File lib/dm-core/property.rb, line 559
    def required?
      @required
    end

serial?() click to toggle source

Returns whether or not the property is "serial" (auto-incrementing)

@return [Boolean]

    whether or not the property is "serial"

@api public

    # File lib/dm-core/property.rb, line 549
    def serial?
      @serial
    end

set(resource, value) click to toggle source

Provides a standardized setter method for the property

@param [Resource] resource

    the resource to get the value from

@param [Object] value

    the value to set in the resource

@return [Object]

    +value+ after being typecasted according to this property's primitive

@raise [ArgumentError] "`resource` should be a Resource, but was ...."

@api private

    # File lib/dm-core/property.rb, line 624
    def set(resource, value)
      set!(resource, value)
    end

set!(resource, value) click to toggle source

Set the ivar value in the resource

@param [Resource] resource

    the resource to set

@param [Object] value

    the value to set in the resource

@return [Object]

    the value set in the resource

@api private

    # File lib/dm-core/property.rb, line 639
    def set!(resource, value)
      resource.instance_variable_set(instance_variable_name, value)
    end

typecast(value) click to toggle source

@api semipublic

    # File lib/dm-core/property.rb, line 682
    def typecast(value)
      if value.nil? || primitive?(value)
        value
      elsif respond_to?(:typecast_to_primitive, true)
        typecast_to_primitive(value)
      else
        value
      end
    end

unique?() click to toggle source

Returns true if property is unique. Serial properties and keys are unique by default.

@return [Boolean]

    true if property has uniq index defined, false otherwise

@api public

    # File lib/dm-core/property.rb, line 496
    def unique?
      !!@unique
    end

valid?(value, negated = false) click to toggle source

Test the value to see if it is a valid value for this Property

@param [Object] loaded_value

    the value to be tested

@return [Boolean]

    true if the value is valid

@api semipulic

    # File lib/dm-core/property.rb, line 701
    def valid?(value, negated = false)
      dumped_value = dump(value)

      if required? && dumped_value.nil?
        negated || false
      else
        primitive?(dumped_value) || (dumped_value.nil? && (allow_nil? || negated))
      end
    end

### Protected Instance Methods

assert_valid_options(options) click to toggle source

@api private

    # File lib/dm-core/property.rb, line 775
    def assert_valid_options(options)
      keys = options.keys

      if (unknown_keys = keys - self.class.accepted_options).any?
        raise ArgumentError, "options #{unknown_keys.map { |key| key.inspect }.join(' and ')} are unknown"
      end

      options.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

determine_visibility() click to toggle source

Assert given visibility value is supported.

Will raise ArgumentError if this Property's reader and writer visibilities are not included in VISIBILITY_OPTIONS.

@return [undefined]

@raise [ArgumentError] "property visibility must be :public, :protected, or :private"

@api private

    # File lib/dm-core/property.rb, line 834
    def determine_visibility
      default_accessor = @options.fetch(:accessor, :public)

      @reader_visibility = @options.fetch(:reader, default_accessor)
      @writer_visibility = @options.fetch(:writer, default_accessor)
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.