mirror of
https://github.com/github/rails.git
synced 2026-01-26 14:58:11 -05:00
Merge branch 'master' into i18n
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
# encoding: utf-8
|
||||
require 'abstract_unit'
|
||||
|
||||
RequestMock = Struct.new("Request", :request_uri, :protocol, :host_with_port, :env)
|
||||
|
||||
@@ -213,7 +213,7 @@ module ActiveRecord
|
||||
|
||||
# Array#flatten has problems with recursive arrays. Going one level deeper solves the majority of the problems.
|
||||
def flatten_deeper(array)
|
||||
array.collect { |element| element.respond_to?(:flatten) ? element.flatten : element }.flatten
|
||||
array.collect { |element| (element.respond_to?(:flatten) && !element.is_a?(Hash)) ? element.flatten : element }.flatten
|
||||
end
|
||||
|
||||
def owner_quoted_id
|
||||
|
||||
@@ -384,12 +384,8 @@ module ActiveRecord
|
||||
def add_column_options!(sql, options) #:nodoc:
|
||||
sql << " DEFAULT #{quote(options[:default], options[:column])}" if options_include_default?(options)
|
||||
# must explicitly check for :null to allow change_column to work on migrations
|
||||
if options.has_key? :null
|
||||
if options[:null] == false
|
||||
sql << " NOT NULL"
|
||||
else
|
||||
sql << " NULL"
|
||||
end
|
||||
if options[:null] == false
|
||||
sql << " NOT NULL"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@ class ColumnDefinitionTest < ActiveRecord::TestCase
|
||||
end
|
||||
|
||||
# Avoid column definitions in create table statements like:
|
||||
# `title` varchar(255) DEFAULT NULL NULL
|
||||
# `title` varchar(255) DEFAULT NULL
|
||||
def test_should_not_include_default_clause_when_default_is_null
|
||||
column = ActiveRecord::ConnectionAdapters::Column.new("title", nil, "varchar(20)")
|
||||
column_def = ActiveRecord::ConnectionAdapters::ColumnDefinition.new(
|
||||
@adapter, column.name, "string",
|
||||
column.limit, column.precision, column.scale, column.default, column.null)
|
||||
assert_equal "title varchar(20) NULL", column_def.to_sql
|
||||
assert_equal "title varchar(20)", column_def.to_sql
|
||||
end
|
||||
|
||||
def test_should_include_default_clause_when_default_is_present
|
||||
@@ -23,7 +23,7 @@ class ColumnDefinitionTest < ActiveRecord::TestCase
|
||||
column_def = ActiveRecord::ConnectionAdapters::ColumnDefinition.new(
|
||||
@adapter, column.name, "string",
|
||||
column.limit, column.precision, column.scale, column.default, column.null)
|
||||
assert_equal %Q{title varchar(20) DEFAULT 'Hello' NULL}, column_def.to_sql
|
||||
assert_equal %Q{title varchar(20) DEFAULT 'Hello'}, column_def.to_sql
|
||||
end
|
||||
|
||||
def test_should_specify_not_null_if_null_option_is_false
|
||||
@@ -33,4 +33,4 @@ class ColumnDefinitionTest < ActiveRecord::TestCase
|
||||
column.limit, column.precision, column.scale, column.default, column.null)
|
||||
assert_equal %Q{title varchar(20) DEFAULT 'Hello' NOT NULL}, column_def.to_sql
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -39,12 +39,16 @@ module ActiveSupport
|
||||
# Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.
|
||||
# The replacement should always be a string that may include references to the matched data from the rule.
|
||||
def plural(rule, replacement)
|
||||
@uncountables.delete(rule) if rule.is_a?(String)
|
||||
@uncountables.delete(replacement)
|
||||
@plurals.insert(0, [rule, replacement])
|
||||
end
|
||||
|
||||
# Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression.
|
||||
# The replacement should always be a string that may include references to the matched data from the rule.
|
||||
def singular(rule, replacement)
|
||||
@uncountables.delete(rule) if rule.is_a?(String)
|
||||
@uncountables.delete(replacement)
|
||||
@singulars.insert(0, [rule, replacement])
|
||||
end
|
||||
|
||||
@@ -55,6 +59,8 @@ module ActiveSupport
|
||||
# irregular 'octopus', 'octopi'
|
||||
# irregular 'person', 'people'
|
||||
def irregular(singular, plural)
|
||||
@uncountables.delete(singular)
|
||||
@uncountables.delete(plural)
|
||||
if singular[0,1].upcase == plural[0,1].upcase
|
||||
plural(Regexp.new("(#{singular[0,1]})#{singular[1..-1]}$", "i"), '\1' + plural[1..-1])
|
||||
singular(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + singular[1..-1])
|
||||
@@ -273,32 +279,47 @@ module ActiveSupport
|
||||
underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
|
||||
end
|
||||
|
||||
# Tries to find a constant with the name specified in the argument string:
|
||||
#
|
||||
# "Module".constantize # => Module
|
||||
# "Test::Unit".constantize # => Test::Unit
|
||||
#
|
||||
# The name is assumed to be the one of a top-level constant, no matter whether
|
||||
# it starts with "::" or not. No lexical context is taken into account:
|
||||
#
|
||||
# C = 'outside'
|
||||
# module M
|
||||
# C = 'inside'
|
||||
# C # => 'inside'
|
||||
# "C".constantize # => 'outside', same as ::C
|
||||
# end
|
||||
#
|
||||
# NameError is raised when the name is not in CamelCase or the constant is
|
||||
# unknown.
|
||||
def constantize(camel_cased_word)
|
||||
names = camel_cased_word.split('::')
|
||||
names.shift if names.empty? || names.first.empty?
|
||||
# Ruby 1.9 introduces an inherit argument for Module#const_get and
|
||||
# #const_defined? and changes their default behavior.
|
||||
if Module.method(:const_get).arity == 1
|
||||
# Tries to find a constant with the name specified in the argument string:
|
||||
#
|
||||
# "Module".constantize # => Module
|
||||
# "Test::Unit".constantize # => Test::Unit
|
||||
#
|
||||
# The name is assumed to be the one of a top-level constant, no matter whether
|
||||
# it starts with "::" or not. No lexical context is taken into account:
|
||||
#
|
||||
# C = 'outside'
|
||||
# module M
|
||||
# C = 'inside'
|
||||
# C # => 'inside'
|
||||
# "C".constantize # => 'outside', same as ::C
|
||||
# end
|
||||
#
|
||||
# NameError is raised when the name is not in CamelCase or the constant is
|
||||
# unknown.
|
||||
def constantize(camel_cased_word)
|
||||
names = camel_cased_word.split('::')
|
||||
names.shift if names.empty? || names.first.empty?
|
||||
|
||||
constant = Object
|
||||
names.each do |name|
|
||||
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
||||
constant = Object
|
||||
names.each do |name|
|
||||
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
||||
end
|
||||
constant
|
||||
end
|
||||
else
|
||||
def constantize(camel_cased_word) #:nodoc:
|
||||
names = camel_cased_word.split('::')
|
||||
names.shift if names.empty? || names.first.empty?
|
||||
|
||||
constant = Object
|
||||
names.each do |name|
|
||||
constant = constant.const_get(name, false) || constant.const_missing(name)
|
||||
end
|
||||
constant
|
||||
end
|
||||
constant
|
||||
end
|
||||
|
||||
# Turns a number into an ordinal string used to denote the position in an
|
||||
|
||||
@@ -183,8 +183,8 @@ module I18n
|
||||
# keys are Symbols.
|
||||
def normalize_translation_keys(locale, key, scope)
|
||||
keys = [locale] + Array(scope) + [key]
|
||||
keys = keys.map{|key| key.to_s.split(/\./) }
|
||||
keys.flatten.map{|key| key.to_sym}
|
||||
keys = keys.map{|k| k.to_s.split(/\./) }
|
||||
keys.flatten.map{|k| k.to_sym}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -27,7 +27,7 @@ module I18n
|
||||
|
||||
def translate(locale, key, options = {})
|
||||
raise InvalidLocale.new(locale) if locale.nil?
|
||||
return key.map{|key| translate locale, key, options } if key.is_a? Array
|
||||
return key.map{|k| translate locale, k, options } if key.is_a? Array
|
||||
|
||||
reserved = :scope, :default
|
||||
count, scope, default = options.values_at(:count, *reserved)
|
||||
@@ -74,7 +74,7 @@ module I18n
|
||||
def lookup(locale, key, scope = [])
|
||||
return unless key
|
||||
keys = I18n.send :normalize_translation_keys, locale, key, scope
|
||||
keys.inject(translations){|result, key| result[key.to_sym] or return nil }
|
||||
keys.inject(translations){|result, k| result[k.to_sym] or return nil }
|
||||
end
|
||||
|
||||
# Evaluates a default translation.
|
||||
@@ -147,9 +147,9 @@ module I18n
|
||||
type = File.extname(filename).tr('.', '').downcase
|
||||
raise UnknownFileType.new(type, filename) unless respond_to? :"load_#{type}"
|
||||
data = send :"load_#{type}", filename # TODO raise a meaningful exception if this does not yield a Hash
|
||||
data.each do |locale, data|
|
||||
merge_translations locale, data
|
||||
end
|
||||
data.each do |locale, d|
|
||||
merge_translations locale, d
|
||||
end
|
||||
end
|
||||
|
||||
# Loads a plain Ruby translations file. eval'ing the file must yield
|
||||
|
||||
@@ -34,6 +34,13 @@ class InflectorTest < Test::Unit::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
def test_overwrite_previous_inflectors
|
||||
assert_equal("series", ActiveSupport::Inflector.singularize("series"))
|
||||
ActiveSupport::Inflector.inflections.singular "series", "serie"
|
||||
assert_equal("serie", ActiveSupport::Inflector.singularize("series"))
|
||||
ActiveSupport::Inflector.inflections.uncountable "series" # Return to normal
|
||||
end
|
||||
|
||||
MixtureToTitleCase.each do |before, titleized|
|
||||
define_method "test_titleize_#{before}" do
|
||||
assert_equal(titleized, ActiveSupport::Inflector.titleize(before))
|
||||
|
||||
@@ -37,6 +37,10 @@ module Rails
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
def reference?
|
||||
[ :references, :belongs_to ].include?(self.type)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
class <%= class_name %> < ActiveRecord::Base
|
||||
<% attributes.select(&:reference?).each do |attribute| -%>
|
||||
belongs_to :<%= attribute.name %>
|
||||
<% end -%>
|
||||
end
|
||||
|
||||
@@ -29,4 +29,20 @@ class RailsModelGeneratorTest < GeneratorTestCase
|
||||
assert_generated_column t, :created_at, :timestamp
|
||||
end
|
||||
end
|
||||
|
||||
def test_model_with_reference_attributes_generates_belongs_to_associations
|
||||
run_generator('model', %w(Product name:string supplier:references))
|
||||
|
||||
assert_generated_model_for :product do |body|
|
||||
assert body =~ /^\s+belongs_to :supplier/, "#{body.inspect} should contain 'belongs_to :supplier'"
|
||||
end
|
||||
end
|
||||
|
||||
def test_model_with_belongs_to_attributes_generates_belongs_to_associations
|
||||
run_generator('model', %w(Product name:string supplier:belongs_to))
|
||||
|
||||
assert_generated_model_for :product do |body|
|
||||
assert body =~ /^\s+belongs_to :supplier/, "#{body.inspect} should contain 'belongs_to :supplier'"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user