Working on adding support for allowing dynamic properties

This commit is contained in:
Sam Lown 2010-09-17 23:25:56 +02:00
parent 85cd1308bc
commit 97347e70e3
5 changed files with 43 additions and 7 deletions

View file

@ -71,11 +71,14 @@ but no guarantees!
## Properties
Only attributes with a property definition will be stored be CouchRest Model (as opposed
to a normal CouchRest Document which will store everything). To help prevent confusion,
a property should be considered as the definition of an attribute. An attribute must be associated
with a property, but a property may not have any attributes associated if none have been set.
A property is the definition of an attribute, it describes what the attribute is called, how it should
be type casted, if at all, and other options such as the default value. These replace your typical
`add_column` methods typically found in migrations.
By default only attributes with a property definition will be stored in CouchRest Model, as opposed
to a normal CouchRest Document which will store everything. This however can be disabled using the
`allow_dynamic_properties` configuration option either for all of CouchRest Model, or for specific
models. See the configuration section for more details.
In its simplest form, a property
will only create a getter and setter passing all attribute data directly to the database. Assuming the attribute
@ -290,6 +293,28 @@ you'd like to ensure the ID is unique between several types of document. For exa
Pretty cool!
## Configuration
CouchRest Model supports a few configuration options. These can be set either for the whole Model code
base or for a specific model of your chosing. To configure globally, provide something similar to the
following in your projects loading code:
CouchRestModel::Model::Base.configure do |config|
config.allow_dynamic_properties = true
config.model_type_key = 'couchrest-type'
end
To set for a specific model:
class Cat < CouchRest::Model::Base
allow_dynamic_properties true
end
Options currently avilable are:
* `allow_dynamic_properties` - false by default, when true properties do not need to be defined to be stored, although they will have no accessors.
* `model_type_key` - 'model' by default, useful for migrating from an older CouchRest ExtendedDocument when the default used to be 'couchrest-type'.
## Notable Issues

View file

@ -4,6 +4,7 @@ module CouchRest::Model
extend ActiveSupport::Concern
included do
include CouchRest::Model::Configuration
include CouchRest::Model::AttributeProtection
include CouchRest::Model::Attributes
include CouchRest::Model::Callbacks

View file

@ -9,9 +9,11 @@ module CouchRest
included do
add_config :model_type_key
add_config :allow_dynamic_properties
configure do |config|
config.model_type_key = 'model'
config.allow_dynamic_properties = false
end
end

View file

@ -29,7 +29,7 @@ module CouchRest
def write_attribute(property, value)
prop = find_property!(property)
self[prop.to_s] = prop.cast(self, value)
self[prop.to_s] = prop.is_a?(String) ? value : prop.cast(self, value)
end
def apply_all_property_defaults
@ -41,10 +41,11 @@ module CouchRest
end
private
def find_property!(property)
prop = property.is_a?(Property) ? property : self.class.properties.detect {|p| p.to_s == property.to_s}
raise ArgumentError, "Missing property definition for #{property.to_s}" unless prop
prop
raise ArgumentError, "Missing property definition for #{property.to_s}" unless allow_dynamic_properties or !prop.nil?
prop || property
end
module ClassMethods

View file

@ -88,6 +88,13 @@ describe "Model properties" do
expect { @card.write_attribute(:this_property_should_not_exist, 823) }.to raise_error(ArgumentError)
end
it 'should not raise an error if the property does not exist and dynamic properties are allowed' do
@card.class.allow_dynamic_properties = true
expect { @card.write_attribute(:this_property_should_not_exist, 823) }.to_not raise_error(ArgumentError)
@card.class.allow_dynamic_properties = false
end
it "should let you use write_attribute on readonly properties" do
lambda {
@card.read_only_value = "foo"