aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/CHANGELOG8
-rwxr-xr-xactiverecord/lib/active_record/base.rb71
-rwxr-xr-xactiverecord/test/base_test.rb54
3 files changed, 132 insertions, 1 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index 1fb60d0e6d..e2dfa77e0b 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,13 @@
*SVN*
+* Added keyword-style approach to defining the custom relational bindings #545 [Jamis Buck]. Example:
+
+ class Project < ActiveRecord::Base
+ primary_key "sysid"
+ table_name "XYZ_PROJECT"
+ inheritance_column { original_inheritance_column + "_id" }
+ end
+
* Added an Oracle adapter that works with the Oracle bindings by Yoshida (http://raa.ruby-lang.org/project/oracle/) #564 [Maik Schmidt]
A number of caveats:
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index e763eb381c..c2ecd0121e 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -525,6 +525,75 @@ module ActiveRecord #:nodoc:
"type"
end
+ # Defines an "attribute" method (like #inheritance_column or
+ # #table_name). A new (class) method will be created with the
+ # given name. If a value is specified, the new method will
+ # return that value (as a string). Otherwise, the given block
+ # will be used to compute the value of the method.
+ #
+ # The original method will be aliased, with the new name being
+ # prefixed with "original_". This allows the new method to
+ # access the original value.
+ #
+ # Example:
+ #
+ # class A < ActiveRecord::Base
+ # define_attr_method :primary_key, "sysid"
+ # define_attr_method( :inheritance_column ) do
+ # original_inheritance_column + "_id"
+ # end
+ # end
+ def define_attr_method( name, value=nil, &block )
+ sing = class << self; self; end
+ block = proc { value.to_s } if value
+ sing.send( :alias_method, "original_#{name}", name )
+ sing.send( :define_method, name, &block )
+ end
+
+ # Sets the table name to use to the given value, or (if the value
+ # is nil or false) to the value returned by the given block. (See
+ # #define_attr_method).
+ #
+ # Example:
+ #
+ # class Project < ActiveRecord::Base
+ # set_table_name "project"
+ # end
+ def set_table_name( value=nil, &block )
+ define_attr_method :table_name, value, &block
+ end
+ alias :table_name= :set_table_name
+
+ # Sets the name of the primary key column to use to the given value,
+ # or (if the value is nil or false) to the value returned by the given
+ # block. (See #define_attr_method).
+ #
+ # Example:
+ #
+ # class Project < ActiveRecord::Base
+ # set_primary_key "sysid"
+ # end
+ def set_primary_key( value=nil, &block )
+ define_attr_method :primary_key, value, &block
+ end
+ alias :primary_key= :set_primary_key
+
+ # Sets the name of the inheritance column to use to the given value,
+ # or (if the value # is nil or false) to the value returned by the
+ # given block. (See # #define_attr_method).
+ #
+ # Example:
+ #
+ # class Project < ActiveRecord::Base
+ # set_inheritance_column do
+ # original_inheritance_column + "_id"
+ # end
+ # end
+ def set_inheritance_column( value=nil, &block )
+ define_attr_method :inheritance_column, value, &block
+ end
+ alias :inheritance_column= :set_inheritance_column
+
# Turns the +table_name+ back into a class name following the reverse rules of +table_name+.
def class_name(table_name = table_name) # :nodoc:
# remove any prefix and/or suffix from the table name
@@ -1253,4 +1322,4 @@ module ActiveRecord #:nodoc:
string[0..3] == "--- "
end
end
-end \ No newline at end of file
+end
diff --git a/activerecord/test/base_test.rb b/activerecord/test/base_test.rb
index c1f9a77638..b232949a25 100755
--- a/activerecord/test/base_test.rb
+++ b/activerecord/test/base_test.rb
@@ -706,4 +706,58 @@ class BasicsTest < Test::Unit::TestCase
t2.reload
assert_equal t1.title, t2.title
end
+
+ def test_define_attr_method_with_value
+ k = Class.new( ActiveRecord::Base )
+ k.define_attr_method :table_name, "foo"
+ assert_equal "foo", k.table_name
+ end
+
+ def test_define_attr_method_with_block
+ k = Class.new( ActiveRecord::Base )
+ k.define_attr_method( :primary_key ) { "sys_" + original_primary_key }
+ assert_equal "sys_id", k.primary_key
+ end
+
+ def test_set_table_name_with_value
+ k = Class.new( ActiveRecord::Base )
+ k.table_name = "foo"
+ assert_equal "foo", k.table_name
+ k.set_table_name "bar"
+ assert_equal "bar", k.table_name
+ end
+
+ def test_set_table_name_with_block
+ k = Class.new( ActiveRecord::Base )
+ k.set_table_name { "ks" }
+ assert_equal "ks", k.table_name
+ end
+
+ def test_set_primary_key_with_value
+ k = Class.new( ActiveRecord::Base )
+ k.primary_key = "foo"
+ assert_equal "foo", k.primary_key
+ k.set_primary_key "bar"
+ assert_equal "bar", k.primary_key
+ end
+
+ def test_set_primary_key_with_block
+ k = Class.new( ActiveRecord::Base )
+ k.set_primary_key { "sys_" + original_primary_key }
+ assert_equal "sys_id", k.primary_key
+ end
+
+ def test_set_inheritance_column_with_value
+ k = Class.new( ActiveRecord::Base )
+ k.inheritance_column = "foo"
+ assert_equal "foo", k.inheritance_column
+ k.set_inheritance_column "bar"
+ assert_equal "bar", k.inheritance_column
+ end
+
+ def test_set_inheritance_column_with_block
+ k = Class.new( ActiveRecord::Base )
+ k.set_inheritance_column { original_inheritance_column + "_id" }
+ assert_equal "type_id", k.inheritance_column
+ end
end