diff --git a/lib/data_mapper/property.rb b/lib/data_mapper/property.rb index bf20054..f34c95a 100644 --- a/lib/data_mapper/property.rb +++ b/lib/data_mapper/property.rb @@ -159,7 +159,7 @@ module DataMapper PROPERTY_OPTIONS = [ :public, :protected, :private, :accessor, :reader, :writer, :lazy, :default, :nullable, :key, :serial, :column, :size, :length, - :format, :index, :check, :ordinal, :auto_validation + :format, :index, :check, :ordinal, :auto_validation, :aliases ] VISIBILITY_OPTIONS = [:public, :protected, :private] @@ -176,6 +176,11 @@ module DataMapper database.schema[klass].add_column(@symbolized_name, @type, @options) klass::ATTRIBUTES << @symbolized_name + @property_aliases = [ name ] + if options.is_a?(Hash) && options.has_key?(:aliases) + @property_aliases = @property_aliases.push(options[:aliases]).flatten + end + create_getter! create_setter! auto_validations! unless @options[:auto_validation] == false @@ -203,32 +208,43 @@ module DataMapper # defines the getter for the property def create_getter! - if lazy? - klass.class_eval <<-EOS - #{reader_visibility.to_s} - def #{name} - lazy_load!(#{name.inspect}) - class << self; - attr_accessor #{name.inspect} + @property_aliases.each do |property_alias| + if lazy? + if property_alias == name + klass.class_eval <<-EOS + #{reader_visibility.to_s} + def #{name} + lazy_load!(#{name.inspect}) + class << self; + attr_accessor #{name.inspect} + end + @#{name} + end + EOS + else + klass.class_eval <<-EOS + #{reader_visibility.to_s} + def #{property_alias} + #{name} + end + EOS + end + else + klass.class_eval <<-EOS + #{reader_visibility.to_s} + def #{property_alias} + #{instance_variable_name} end - @#{name} + EOS end - EOS - else - klass.class_eval <<-EOS - #{reader_visibility.to_s} - def #{name} - #{instance_variable_name} - end - EOS - end - if type == :boolean - klass.class_eval <<-EOS - #{reader_visibility.to_s} - def #{name.to_s.ensure_ends_with('?')} - #{instance_variable_name} + if type == :boolean + klass.class_eval <<-EOS + #{reader_visibility.to_s} + def #{property_alias.to_s.ensure_ends_with('?')} + #{instance_variable_name} + end + EOS end - EOS end rescue SyntaxError raise SyntaxError.new(column) @@ -236,23 +252,34 @@ module DataMapper # defines the setter for the property def create_setter! - if lazy? - klass.class_eval <<-EOS - #{writer_visibility.to_s} - def #{name}=(value) - class << self; - attr_accessor #{name.inspect} + @property_aliases.each do |property_alias| + if lazy? + if property_alias == name + klass.class_eval <<-EOS + #{writer_visibility.to_s} + def #{name}=(value) + class << self; + attr_accessor #{name.inspect} + end + @#{name} = value + end + EOS + else + klass.class_eval <<-EOS + #{writer_visibility.to_s} + def #{property_alias}=(value) + #{name} = value + end + EOS end - @#{name} = value - end - EOS - else - klass.class_eval <<-EOS - #{writer_visibility.to_s} - def #{name}=(value) - #{instance_variable_name} = value + else + klass.class_eval <<-EOS + #{writer_visibility.to_s} + def #{property_alias}=(value) + #{instance_variable_name} = value + end + EOS end - EOS end rescue SyntaxError raise SyntaxError.new(column) diff --git a/spec/property_spec.rb b/spec/property_spec.rb index 15daf35..8b1af2d 100644 --- a/spec/property_spec.rb +++ b/spec/property_spec.rb @@ -5,7 +5,7 @@ describe DataMapper::Property do before(:all) do @property = Zoo.properties.find { |property| property.name == :notes } end - + it "should map a column" do @property.column.should eql(database.table(Zoo)[:notes]) end @@ -34,7 +34,57 @@ describe DataMapper::Property do zoo.name = "Content" zoo.valid?.should == true end - + + it "should respond to an aliased field name" do + class AliasedCustomer #< DataMapper::Base # please do not remove this + include DataMapper::Persistence + + property :name, :string, :aliases => [ :customer_name, :business_name ] + end + zoo = AliasedCustomer.new + zoo.respond_to?(:name).should == true + zoo.respond_to?(:customer_name).should == true + zoo.respond_to?(:customer_name=).should == true + zoo.respond_to?(:business_name).should == true + zoo.respond_to?(:business_name=).should == true + end + + it "should respond with the same value for an aliased field" do + zoo = AliasedCustomer.new + zoo.name = 'bob' + zoo.name.should == zoo.customer_name + zoo.name.should == zoo.business_name + zoo.customer_name = 'steve' + zoo.customer_name.should == zoo.name + zoo.customer_name.should == zoo.business_name + end + + it "should respond to an aliased field name that is lazy" do + class LazyAliasedCustomer #< DataMapper::Base # please do not remove this + include DataMapper::Persistence + + property :name, :string, :aliases => [ :customer_name, :business_name ], :lazy => true + end + zoo = LazyAliasedCustomer.new + zoo.respond_to?(:name).should == true + zoo.respond_to?(:customer_name).should == true + zoo.respond_to?(:customer_name=).should == true + zoo.respond_to?(:business_name).should == true + zoo.respond_to?(:business_name=).should == true + end + + it "should respond with the same value for an aliased field that is lazy" do + zoo = LazyAliasedCustomer.new + zoo.name = 'bob' + zoo.name.should == zoo.customer_name + zoo.name.should == zoo.business_name + + zoo = LazyAliasedCustomer.new + zoo.customer_name = 'steve' + zoo.customer_name.should == zoo.name + zoo.customer_name.should == zoo.business_name + end + it "should add a validates_length_of for maximum size" do class SizableZoo #< DataMapper::Base # please do not remove this include DataMapper::Persistence