diff options
11 files changed, 75 insertions, 29 deletions
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb index d91e4a2b6a..f90030641d 100644 --- a/activemodel/lib/active_model/errors.rb +++ b/activemodel/lib/active_model/errors.rb @@ -300,13 +300,17 @@ module ActiveModel def generate_message(attribute, type = :invalid, options = {}) type = options.delete(:message) if options[:message].is_a?(Symbol) - defaults = @base.class.lookup_ancestors.map do |klass| - [ :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.i18n_key}.attributes.#{attribute}.#{type}", - :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.i18n_key}.#{type}" ] + if @base.class.respond_to?(:i18n_scope) + defaults = @base.class.lookup_ancestors.map do |klass| + [ :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.i18n_key}.attributes.#{attribute}.#{type}", + :"#{@base.class.i18n_scope}.errors.models.#{klass.model_name.i18n_key}.#{type}" ] + end + else + defaults = [] end defaults << options.delete(:message) - defaults << :"#{@base.class.i18n_scope}.errors.messages.#{type}" + defaults << :"#{@base.class.i18n_scope}.errors.messages.#{type}" if @base.class.respond_to?(:i18n_scope) defaults << :"errors.attributes.#{attribute}.#{type}" defaults << :"errors.messages.#{type}" diff --git a/activemodel/lib/active_model/secure_password.rb b/activemodel/lib/active_model/secure_password.rb index 7a109d9a52..db78864c67 100644 --- a/activemodel/lib/active_model/secure_password.rb +++ b/activemodel/lib/active_model/secure_password.rb @@ -32,8 +32,8 @@ module ActiveModel # User.find_by_name("david").try(:authenticate, "notright") # => nil # User.find_by_name("david").try(:authenticate, "mUc3m00RsqyRe") # => user def has_secure_password - # Load bcrypt-ruby only when has_secured_password is used to avoid make ActiveModel - # (and by extension the entire framework) dependent on a binary library. + # Load bcrypt-ruby only when has_secure_password is used. + # This is to avoid ActiveModel (and by extension the entire framework) being dependent on a binary library. gem 'bcrypt-ruby', '~> 3.0.0' require 'bcrypt' diff --git a/activemodel/test/cases/errors_test.rb b/activemodel/test/cases/errors_test.rb index 4c76bb43a8..784a2b2709 100644 --- a/activemodel/test/cases/errors_test.rb +++ b/activemodel/test/cases/errors_test.rb @@ -66,6 +66,20 @@ class ErrorsTest < ActiveModel::TestCase assert_equal ["can not be blank"], person.errors[:name] end + test "should be able to add an error with a symbol" do + person = Person.new + person.errors.add(:name, :blank) + message = person.errors.generate_message(:name, :blank) + assert_equal [message], person.errors[:name] + end + + test "should be able to add an error with a proc" do + person = Person.new + message = Proc.new { "can not be blank" } + person.errors.add(:name, message) + assert_equal ["can not be blank"], person.errors[:name] + end + test 'should respond to size' do person = Person.new person.errors.add(:name, "can not be blank") @@ -112,5 +126,12 @@ class ErrorsTest < ActiveModel::TestCase assert_equal ["is invalid"], hash[:email] end + test "generate_message should work without i18n_scope" do + person = Person.new + assert !Person.respond_to?(:i18n_scope) + assert_nothing_raised { + person.errors.generate_message(:name, :blank) + } + end end diff --git a/activemodel/test/cases/secure_password_test.rb b/activemodel/test/cases/secure_password_test.rb index 6950c3be1f..4338a3fc53 100644 --- a/activemodel/test/cases/secure_password_test.rb +++ b/activemodel/test/cases/secure_password_test.rb @@ -10,15 +10,13 @@ class SecurePasswordTest < ActiveModel::TestCase end test "blank password" do - user = User.new - user.password = '' - assert !user.valid?, 'user should be invalid' + @user.password = '' + assert !@user.valid?, 'user should be invalid' end test "nil password" do - user = User.new - user.password = nil - assert !user.valid?, 'user should be invalid' + @user.password = nil + assert !@user.valid?, 'user should be invalid' end test "password must be present" do diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb index 82f564e41d..989a4fcbca 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -252,7 +252,7 @@ module ActiveRecord # Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and # <tt>:updated_at</tt> to the table. def timestamps(*args) - options = args.extract_options! + options = { :null => false }.merge(args.extract_options!) column(:created_at, :datetime, options) column(:updated_at, :datetime, options) end diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 8e3ba1297e..b4a9e29ef1 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -507,8 +507,8 @@ module ActiveRecord # ===== Examples # add_timestamps(:suppliers) def add_timestamps(table_name) - add_column table_name, :created_at, :datetime - add_column table_name, :updated_at, :datetime + add_column table_name, :created_at, :datetime, :null => false + add_column table_name, :updated_at, :datetime, :null => false end # Removes the timestamp columns (created_at and updated_at) from the table definition. diff --git a/activerecord/test/cases/adapters/mysql/case_sensitivity_test.rb b/activerecord/test/cases/adapters/mysql/case_sensitivity_test.rb index 5ffd886dab..97adb6b297 100644 --- a/activerecord/test/cases/adapters/mysql/case_sensitivity_test.rb +++ b/activerecord/test/cases/adapters/mysql/case_sensitivity_test.rb @@ -21,7 +21,7 @@ class MysqlCaseSensitivityTest < ActiveRecord::TestCase CollationTest.create!(:string_ci_column => 'A') invalid = CollationTest.new(:string_ci_column => 'a') queries = assert_sql { invalid.save } - ci_uniqueness_query = queries.detect { |q| q.match /string_ci_column/ } + ci_uniqueness_query = queries.detect { |q| q.match(/string_ci_column/) } assert_no_match(/lower/i, ci_uniqueness_query) end @@ -29,7 +29,7 @@ class MysqlCaseSensitivityTest < ActiveRecord::TestCase CollationTest.create!(:string_cs_column => 'A') invalid = CollationTest.new(:string_cs_column => 'a') queries = assert_sql { invalid.save } - cs_uniqueness_query = queries.detect { |q| q.match /string_cs_column/ } + cs_uniqueness_query = queries.detect { |q| q.match(/string_cs_column/) } assert_match(/lower/i, cs_uniqueness_query) end end diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb index 93a1249e43..4b5dd18be8 100644 --- a/activerecord/test/cases/migration_test.rb +++ b/activerecord/test/cases/migration_test.rb @@ -389,8 +389,8 @@ if ActiveRecord::Base.connection.supports_migrations? created_at_column = created_columns.detect {|c| c.name == 'created_at' } updated_at_column = created_columns.detect {|c| c.name == 'updated_at' } - assert created_at_column.null - assert updated_at_column.null + assert !created_at_column.null + assert !updated_at_column.null ensure Person.connection.drop_table table_name rescue nil end @@ -471,11 +471,11 @@ if ActiveRecord::Base.connection.supports_migrations? # Do a manual insertion if current_adapter?(:OracleAdapter) - Person.connection.execute "insert into people (id, wealth) values (people_seq.nextval, 12345678901234567890.0123456789)" + Person.connection.execute "insert into people (id, wealth, created_at, updated_at) values (people_seq.nextval, 12345678901234567890.0123456789, 0, 0)" elsif current_adapter?(:OpenBaseAdapter) || (current_adapter?(:MysqlAdapter) && Mysql.client_version < 50003) #before mysql 5.0.3 decimals stored as strings - Person.connection.execute "insert into people (wealth) values ('12345678901234567890.0123456789')" + Person.connection.execute "insert into people (wealth, created_at, updated_at) values ('12345678901234567890.0123456789', 0, 0)" else - Person.connection.execute "insert into people (wealth) values (12345678901234567890.0123456789)" + Person.connection.execute "insert into people (wealth, created_at, updated_at) values (12345678901234567890.0123456789, 0, 0)" end # SELECT diff --git a/activesupport/lib/active_support/core_ext/string/inflections.rb b/activesupport/lib/active_support/core_ext/string/inflections.rb index c7ceeb9de4..fd91b3cacb 100644 --- a/activesupport/lib/active_support/core_ext/string/inflections.rb +++ b/activesupport/lib/active_support/core_ext/string/inflections.rb @@ -9,14 +9,25 @@ require 'active_support/inflector/transliterate' class String # Returns the plural form of the word in the string. # + # If the optional parameter +count+ is specified, + # the singular form will be returned if <tt>count == 1</tt>. + # For any other value of +count+ the plural will be returned. + # + # ==== Examples # "post".pluralize # => "posts" # "octopus".pluralize # => "octopi" # "sheep".pluralize # => "sheep" # "words".pluralize # => "words" # "the blue mailman".pluralize # => "the blue mailmen" # "CamelOctopus".pluralize # => "CamelOctopi" - def pluralize - ActiveSupport::Inflector.pluralize(self) + # "apple".pluralize(1) # => "apple" + # "apple".pluralize(2) # => "apples" + def pluralize(count = nil) + if count == 1 + self + else + ActiveSupport::Inflector.pluralize(self) + end end # The reverse of +pluralize+, returns the singular form of a word in a string. @@ -42,7 +53,7 @@ class String def constantize ActiveSupport::Inflector.constantize(self) end - + # +safe_constantize+ tries to find a declared constant with the name specified # in the string. It returns nil when the name is not in CamelCase # or is not initialized. See ActiveSupport::Inflector.safe_constantize diff --git a/activesupport/test/core_ext/string_ext_test.rb b/activesupport/test/core_ext/string_ext_test.rb index 5c1dddaf96..4d876954cf 100644 --- a/activesupport/test/core_ext/string_ext_test.rb +++ b/activesupport/test/core_ext/string_ext_test.rb @@ -20,7 +20,7 @@ end class StringInflectionsTest < Test::Unit::TestCase include InflectorTestCases include ConstantizeTestCases - + def test_erb_escape string = [192, 60].pack('CC') expected = 192.chr + "<" @@ -64,6 +64,10 @@ class StringInflectionsTest < Test::Unit::TestCase end assert_equal("plurals", "plurals".pluralize) + + assert_equal("blargles", "blargle".pluralize(0)) + assert_equal("blargle", "blargle".pluralize(1)) + assert_equal("blargles", "blargle".pluralize(2)) end def test_singularize @@ -301,13 +305,13 @@ class StringInflectionsTest < Test::Unit::TestCase "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".force_encoding('UTF-8').truncate(10) end end - + def test_constantize run_constantize_tests_on do |string| string.constantize end end - + def test_safe_constantize run_safe_constantize_tests_on do |string| string.safe_constantize @@ -381,7 +385,7 @@ class OutputSafetyTest < ActiveSupport::TestCase test "A fixnum is safe by default" do assert 5.html_safe? end - + test "a float is safe by default" do assert 5.7.html_safe? end diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile index ecc25c4f1c..c04e49281e 100644 --- a/railties/guides/source/active_support_core_extensions.textile +++ b/railties/guides/source/active_support_core_extensions.textile @@ -1426,6 +1426,14 @@ The method +pluralize+ returns the plural of its receiver: As the previous example shows, Active Support knows some irregular plurals and uncountable nouns. Built-in rules can be extended in +config/initializers/inflections.rb+. That file is generated by the +rails+ command and has instructions in comments. ++pluralize+ can also take an optional +count+ parameter. If <tt>count == 1</tt> the singular form will be returned. For any other value of +count+ the plural form will be returned: + +<ruby> +"dude".pluralize(0) # => "dudes" +"dude".pluralize(1) # => "dude" +"dude".pluralize(2) # => "dudes" +</ruby> + Active Record uses this method to compute the default table name that corresponds to a model: <ruby> |