aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2004-12-19 11:25:55 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2004-12-19 11:25:55 +0000
commit7b5ed66122873eebb773a6418f3a94d946cc4f8c (patch)
tree63c77291a6c78c7446bb5041b062bc8485a0fb5f
parent61960e7b37767140e9af68bd5373e06dce08492d (diff)
downloadrails-7b5ed66122873eebb773a6418f3a94d946cc4f8c.tar.gz
rails-7b5ed66122873eebb773a6418f3a94d946cc4f8c.tar.bz2
rails-7b5ed66122873eebb773a6418f3a94d946cc4f8c.zip
Added respondence to *_before_type_cast for all attributes to return their string-state before they were type casted by the column type. Added use of *_before_type_cast for all input and text fields.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@215 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
-rw-r--r--actionpack/CHANGELOG3
-rw-r--r--actionpack/lib/action_view/helpers/active_record_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb14
-rw-r--r--actionpack/test/template/active_record_helper_test.rb5
-rw-r--r--actionpack/test/template/form_helper_test.rb7
-rw-r--r--activerecord/CHANGELOG3
-rwxr-xr-xactiverecord/lib/active_record/base.rb23
-rwxr-xr-xactiverecord/test/abstract_unit.rb2
-rw-r--r--activerecord/test/fixtures/developer.rb6
-rw-r--r--activerecord/test/fixtures/developers.yml3
-rwxr-xr-xactiverecord/test/validations_test.rb9
11 files changed, 55 insertions, 22 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index 548c9b530f..d81c12f027 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,5 +1,8 @@
*SVN*
+* Added use of *_before_type_cast for all input and text fields. This is helpful for getting "100,000" back on a integer-based
+ validation where the value would normally be "100".
+
* Added Request#port_string to get something like ":8080" back on 8080 and "" on 80 (or 443 with https).
* Added Request#domain (returns string) and Request#subdomains (returns array).
diff --git a/actionpack/lib/action_view/helpers/active_record_helper.rb b/actionpack/lib/action_view/helpers/active_record_helper.rb
index 07ede179e6..6855fa49c5 100644
--- a/actionpack/lib/action_view/helpers/active_record_helper.rb
+++ b/actionpack/lib/action_view/helpers/active_record_helper.rb
@@ -132,7 +132,6 @@ module ActionView
end
alias_method :tag_without_error_wrapping, :tag
-
def tag(name, options)
if object.respond_to?("errors") && object.errors.respond_to?("on")
error_wrapping(tag_without_error_wrapping(name, options), object.errors.on(@method_name))
@@ -142,7 +141,6 @@ module ActionView
end
alias_method :content_tag_without_error_wrapping, :content_tag
-
def content_tag(name, value, options)
if object.respond_to?("errors") && object.errors.respond_to?("on")
error_wrapping(content_tag_without_error_wrapping(name, value, options), object.errors.on(@method_name))
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 253b389a79..d9a1c7d55e 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -135,15 +135,15 @@ module ActionView
html_options.merge!({ "size" => options["maxlength"]}) if options["maxlength"] && !options["size"]
html_options.delete("size") if field_type == "hidden"
html_options.merge!({ "type" => field_type})
- html_options.merge!({ "value" => value.to_s }) unless options["value"]
+ html_options.merge!({ "value" => value_before_type_cast }) unless options["value"]
add_default_name_and_id(html_options)
tag("input", html_options)
end
def to_radio_button_tag(tag_value, options={})
html_options = DEFAULT_FIELD_OPTIONS.merge(options)
- html_options.merge!({"checked"=>"checked"}) if value == tag_value
- html_options.merge!({"type"=>"radio", "value"=>tag_value.to_s})
+ html_options.merge!({ "checked" => "checked" }) if value == tag_value
+ html_options.merge!({ "type" => "radio", "value"=> tag_value.to_s })
add_default_name_and_id(html_options)
tag("input", html_options)
@@ -152,11 +152,11 @@ module ActionView
def to_text_area_tag(options = {})
options = DEFAULT_TEXT_AREA_OPTIONS.merge(options)
add_default_name_and_id(options)
- content_tag("textarea", html_escape(value), options)
+ content_tag("textarea", html_escape(value_before_type_cast), options)
end
def to_check_box_tag(options = {}, checked_value = "1", unchecked_value = "0")
- options.merge!({"checked" => "checked"}) if !value.nil? && ((value.is_a?(TrueClass) || value.is_a?(FalseClass)) ? value : value.to_i > 0)
+ options.merge!({ "checked" => "checked" }) if !value.nil? && ((value.is_a?(TrueClass) || value.is_a?(FalseClass)) ? value : value.to_i > 0)
options.merge!({ "type" => "checkbox", "value" => checked_value })
add_default_name_and_id(options)
tag("input", options) << tag("input", ({ "name" => options['name'], "type" => "hidden", "value" => unchecked_value }))
@@ -191,6 +191,10 @@ module ActionView
object.send(@method_name) unless object.nil?
end
+ def value_before_type_cast
+ object.send(@method_name + "_before_type_cast") unless object.nil?
+ end
+
private
def add_default_name_and_id(options)
options['name'] = tag_name unless options.has_key? "name"
diff --git a/actionpack/test/template/active_record_helper_test.rb b/actionpack/test/template/active_record_helper_test.rb
index f9a2727067..e650b4f0b8 100644
--- a/actionpack/test/template/active_record_helper_test.rb
+++ b/actionpack/test/template/active_record_helper_test.rb
@@ -14,6 +14,11 @@ class ActiveRecordHelperTest < Test::Unit::TestCase
include ActionView::Helpers::UrlHelper
Post = Struct.new("Post", :title, :author_name, :body, :secret, :written_on)
+ Post.class_eval do
+ alias_method :title_before_type_cast, :title unless respond_to?(:title_before_type_cast)
+ alias_method :body_before_type_cast, :body unless respond_to?(:body_before_type_cast)
+ alias_method :author_name_before_type_cast, :author_name unless respond_to?(:author_name_before_type_cast)
+ end
Column = Struct.new("Column", :type, :name, :human_name)
def setup
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index d81e2ac270..c6128a9337 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -6,7 +6,12 @@ class FormHelperTest < Test::Unit::TestCase
include ActionView::Helpers::FormHelper
old_verbose, $VERBOSE = $VERBOSE, nil
- Post = Struct.new("Post", :title, :author_name, :body, :secret, :written_on)
+ Post = Struct.new("Post", :title, :author_name, :body, :secret, :written_on, :cost)
+ Post.class_eval do
+ alias_method :title_before_type_cast, :title unless respond_to?(:title_before_type_cast)
+ alias_method :body_before_type_cast, :body unless respond_to?(:body_before_type_cast)
+ alias_method :author_name_before_type_cast, :author_name unless respond_to?(:author_name_before_type_cast)
+ end
$VERBOSE = old_verbose
def setup
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG
index e9927ae980..573fa9f618 100644
--- a/activerecord/CHANGELOG
+++ b/activerecord/CHANGELOG
@@ -1,5 +1,8 @@
*SVN*
+* Added respondence to *_before_type_cast for all attributes to return their string-state before they were type casted by the column type.
+ This is helpful for getting "100,000" back on a integer-based validation where the value would normally be "100".
+
* Fixed the automated timestamping feature when running under Rails' development environment that resets the inheritable attributes on each request.
* Added Base#update_attributes that'll accept a hash of attributes and save the record (returning true if it passed validation, false otherwise).
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index b0de050185..38002ad2a0 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -920,10 +920,10 @@ module ActiveRecord #:nodoc:
def method_missing(method_id, *arguments)
method_name = method_id.id2name
-
-
if method_name =~ read_method? && @attributes.include?($1)
return read_attribute($1)
+ elsif method_name =~ read_untyped_method? && @attributes.include?($1)
+ return read_attribute_before_type_cast($1)
elsif method_name =~ write_method? && @attributes.include?($1)
write_attribute($1, arguments[0])
elsif method_name =~ query_method? && @attributes.include?($1)
@@ -933,25 +933,30 @@ module ActiveRecord #:nodoc:
end
end
- def read_method?() /^([a-zA-Z][-_\w]*)[^=?]*$/ end
- def write_method?() /^([a-zA-Z][-_\w]*)=.*$/ end
- def query_method?() /^([a-zA-Z][-_\w]*)\?$/ end
+ def read_method?() /^([a-zA-Z][-_\w]*)[^=?]*$/ end
+ def read_untyped_method?() /^([a-zA-Z][-_\w]*)_before_type_cast$/ end
+ def write_method?() /^([a-zA-Z][-_\w]*)=.*$/ end
+ def query_method?() /^([a-zA-Z][-_\w]*)\?$/ end
- # Returns the value of attribute identified by <tt>attr_name</tt> after it has been type cast (for example,
+ # Returns the value of attribute identified by <tt>attr_name</tt> after it has been type cast (for example,
# "2004-12-12" in a data column is cast to a date object, like Date.new(2004, 12, 12)).
def read_attribute(attr_name) #:doc:
if @attributes.keys.include? attr_name
if column = column_for_attribute(attr_name)
- @attributes[attr_name] = unserializable_attribute?(attr_name, column) ?
+ unserializable_attribute?(attr_name, column) ?
unserialize_attribute(attr_name) : column.type_cast(@attributes[attr_name])
+ else
+ @attributes[attr_name]
end
-
- @attributes[attr_name]
else
nil
end
end
+ def read_attribute_before_type_cast(attr_name)
+ @attributes[attr_name]
+ end
+
# Returns true if the attribute is of a text column and marked for serialization.
def unserializable_attribute?(attr_name, column)
@attributes[attr_name] && column.send(:type) == :text && @attributes[attr_name].is_a?(String) && self.class.serialized_attributes[attr_name]
diff --git a/activerecord/test/abstract_unit.rb b/activerecord/test/abstract_unit.rb
index 293f3ba6b3..67984a4609 100755
--- a/activerecord/test/abstract_unit.rb
+++ b/activerecord/test/abstract_unit.rb
@@ -4,6 +4,8 @@ $:.unshift(File.dirname(__FILE__) + '/../lib')
require 'test/unit'
require 'active_record'
require 'active_record/fixtures'
+require 'active_record/support/binding_of_caller'
+require 'active_record/support/breakpoint'
require 'connection'
class Test::Unit::TestCase #:nodoc:
diff --git a/activerecord/test/fixtures/developer.rb b/activerecord/test/fixtures/developer.rb
index 1c4cc30506..78f8f54db7 100644
--- a/activerecord/test/fixtures/developer.rb
+++ b/activerecord/test/fixtures/developer.rb
@@ -1,8 +1,6 @@
class Developer < ActiveRecord::Base
has_and_belongs_to_many :projects
- protected
- def validate
- errors.add_on_boundary_breaking("name", 3..20)
- end
+ validates_inclusion_of :salary, :in => 50000..200000
+ validates_length_of :name, :within => 3..20
end
diff --git a/activerecord/test/fixtures/developers.yml b/activerecord/test/fixtures/developers.yml
index 733455f789..fc33af99b6 100644
--- a/activerecord/test/fixtures/developers.yml
+++ b/activerecord/test/fixtures/developers.yml
@@ -1,13 +1,16 @@
david:
id: 1
name: David
+ salary: 80000
jamis:
id: 2
name: Jamis
+ salary: 150000
<% for digit in 3..10 %>
dev_<%= digit %>:
id: <%= digit %>
name: fixture_<%= digit %>
+ salary: 100000
<% end %> \ No newline at end of file
diff --git a/activerecord/test/validations_test.rb b/activerecord/test/validations_test.rb
index b6c9cfed7d..8949206706 100755
--- a/activerecord/test/validations_test.rb
+++ b/activerecord/test/validations_test.rb
@@ -348,4 +348,11 @@ class ValidationsTest < Test::Unit::TestCase
assert_equal "hoo 5", t.errors["title"]
end
-end
+
+ def test_throw_away_typing
+ d = Developer.create "name" => "David", "salary" => "100,000"
+ assert !d.valid?
+ assert_not_equal "100,000", d.salary
+ assert_equal "100,000", d.salary_before_type_cast
+ end
+end \ No newline at end of file