module DataMapper::Model::Property
Public Class Methods
# File lib/dm-core/model/property.rb, line 9 def self.extended(model) model.instance_variable_set(:@properties, {}) model.instance_variable_set(:@field_naming_conventions, {}) end
Public Instance Methods
Gets the field naming conventions for this resource in the given Repository
@param [String, Symbol] repository_name
the name of the Repository for which the field naming convention will be retrieved
@return [#call]
The naming convention for the given Repository
@api public
# File lib/dm-core/model/property.rb, line 159 def field_naming_convention(repository_name = default_storage_name) @field_naming_conventions[repository_name] ||= repository(repository_name).adapter.field_naming_convention end
# File lib/dm-core/model/property.rb, line 15 def inherited(model) model.instance_variable_set(:@properties, {}) model.instance_variable_set(:@field_naming_conventions, @field_naming_conventions.dup) @properties.each do |repository_name, properties| model_properties = model.properties(repository_name) properties.each { |property| model_properties << property } end super end
Gets the list of key fields for this Model in
repository_name
@param [String] repository_name
The name of the Repository for which the key is to be reported
@return [Array]
The list of key fields for this Model in +repository_name+
@api public
# File lib/dm-core/model/property.rb, line 140 def key(repository_name = default_repository_name) properties(repository_name).key end
@api private
# File lib/dm-core/model/property.rb, line 177 def key_conditions(repository, key) Hash[ self.key(repository.name).zip(key.nil? ? [] : key) ] end
Gets a list of all properties that have been defined on this Model in the requested repository
@param [Symbol, String] repository_name
The name of the repository to use. Uses the default Repository if none is specified.
@return [PropertySet]
A list of Properties defined on this Model in the given Repository
@api public
# File lib/dm-core/model/property.rb, line 116 def properties(repository_name = default_repository_name) # TODO: create PropertySet#copy that will copy the properties, but assign the # new Relationship objects to a supplied repository and model. dup does not really # do what is needed repository_name = repository_name.to_sym default_repository_name = self.default_repository_name @properties[repository_name] ||= if repository_name == default_repository_name PropertySet.new else properties(default_repository_name).dup end end
@api private
# File lib/dm-core/model/property.rb, line 164 def properties_with_subclasses(repository_name = default_repository_name) properties = properties(repository_name).dup descendants.each do |model| model.properties(repository_name).each do |property| properties << property end end properties end
Defines a Property on the Resource
@param [Symbol] name
the name for which to call this property
@param [Class] type
the ruby type to define this property as
@param [Hash(Symbol => String)] options
a hash of available options
@return [Property]
the created Property
@see Property
@api public
# File lib/dm-core/model/property.rb, line 42 def property(name, type, options = {}) if TrueClass == type raise "#{type} is deprecated, use Boolean instead at #{caller[2]}" elsif BigDecimal == type raise "#{type} is deprecated, use Decimal instead at #{caller[2]}" end # if the type can be found within Property then # use that class rather than the primitive unless klass = DataMapper::Property.determine_class(type) raise ArgumentError, "+type+ was #{type.inspect}, which is not a supported type" end property = klass.new(self, name, options) repository_name = self.repository_name properties = properties(repository_name) properties << property # Add property to the other mappings as well if this is for the default # repository. if repository_name == default_repository_name other_repository_properties = DataMapper::Ext::Hash.except(@properties, default_repository_name) other_repository_properties.each do |other_repository_name, properties| next if properties.named?(name) # make sure the property is created within the correct repository scope DataMapper.repository(other_repository_name) do properties << klass.new(self, name, options) end end end # Add the property to the lazy_loads set for this resources repository # only. # TODO Is this right or should we add the lazy contexts to all # repositories? if property.lazy? context = options.fetch(:lazy, :default) context = :default if context == true Array(context).each do |context| properties.lazy_context(context) << property end end # add the property to the child classes only if the property was # added after the child classes' properties have been copied from # the parent descendants.each do |descendant| descendant.properties(repository_name) << property end create_reader_for(property) create_writer_for(property) # FIXME: explicit return needed for YARD to parse this properly return property end
@api public
# File lib/dm-core/model/property.rb, line 145 def serial(repository_name = default_repository_name) key(repository_name).detect { |property| property.serial? } end
Private Instance Methods
defines the reader method for the property
@api private
# File lib/dm-core/model/property.rb, line 200 def create_reader_for(property) name = property.name.to_s reader_visibility = property.reader_visibility instance_variable_name = property.instance_variable_name property_module.module_eval " #{reader_visibility} def #{name} return #{instance_variable_name} if defined?(#{instance_variable_name}) property = properties[#{name.inspect}] #{instance_variable_name} = property ? persistence_state.get(property) : nil end ", __FILE__, __LINE__ + 1 boolean_reader_name = "#{name}?" if property.kind_of?(DataMapper::Property::Boolean) property_module.module_eval " #{reader_visibility} def #{boolean_reader_name} #{name} end ", __FILE__, __LINE__ + 1 end end
defines the setter for the property
@api private
# File lib/dm-core/model/property.rb, line 228 def create_writer_for(property) name = property.name writer_visibility = property.writer_visibility writer_name = "#{name}=" property_module.module_eval " #{writer_visibility} def #{writer_name}(value) property = properties[#{name.inspect}] value = property.typecast(value) self.persistence_state = persistence_state.set(property, value) persistence_state.get(property) end ", __FILE__, __LINE__ + 1 end
@api public
# File lib/dm-core/model/property.rb, line 245 def method_missing(method, *args, &block) if property = properties(repository_name)[method] return property end super end
Defines the anonymous module that is used to add properties. Using a single module here prevents having a very large number of anonymous modules, where each property has their own module. @api private
# File lib/dm-core/model/property.rb, line 187 def property_module @property_module ||= begin mod = Module.new class_eval do include mod end mod end end