提交 53e2e8ef 编写于 作者: J Jeremy Kemper

Merge branch 'master' into i18n

# encoding: utf-8
require 'abstract_unit'
RequestMock = Struct.new("Request", :request_uri, :protocol, :host_with_port, :env)
......
......@@ -213,7 +213,7 @@ def raise_on_type_mismatch(record)
# 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 @@ def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
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 @@ def @adapter.native_database_types
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 @@ def test_should_include_default_clause_when_default_is_present
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 @@ def test_should_specify_not_null_if_null_option_is_false
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
\ No newline at end of file
end
......@@ -39,12 +39,16 @@ def initialize
# 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 @@ def singular(rule, replacement)
# 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 @@ def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
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)
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_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
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 @@ def default_exception_handler(exception, locale, key, options)
# 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 @@ def store_translations(locale, data)
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 @@ def translations
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 @@ def load_file(filename)
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 @@ def test_pluralize_empty_string
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 @@ def default
""
end
end
def reference?
[ :references, :belongs_to ].include?(self.type)
end
end
end
end
class <%= class_name %> < ActiveRecord::Base
<% attributes.select(&:reference?).each do |attribute| -%>
belongs_to :<%= attribute.name %>
<% end -%>
end
......@@ -29,4 +29,20 @@ def test_model_with_attributes_generates_resources_with_attributes
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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册