diff --git a/README.md b/README.md index a4669b5..01081e9 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/lib/couchrest/model/casted_model.rb b/lib/couchrest/model/casted_model.rb index 9ef1603..8dc2f9e 100644 --- a/lib/couchrest/model/casted_model.rb +++ b/lib/couchrest/model/casted_model.rb @@ -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 diff --git a/lib/couchrest/model/configuration.rb b/lib/couchrest/model/configuration.rb index c468a02..2dd9c88 100644 --- a/lib/couchrest/model/configuration.rb +++ b/lib/couchrest/model/configuration.rb @@ -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 diff --git a/lib/couchrest/model/properties.rb b/lib/couchrest/model/properties.rb index 399673e..d6981a3 100644 --- a/lib/couchrest/model/properties.rb +++ b/lib/couchrest/model/properties.rb @@ -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 diff --git a/spec/couchrest/property_spec.rb b/spec/couchrest/property_spec.rb index 95352a9..cbcc00f 100644 --- a/spec/couchrest/property_spec.rb +++ b/spec/couchrest/property_spec.rb @@ -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"