mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
Merge branch 'master' of github.com:rails/rails
This commit is contained in:
@@ -59,7 +59,7 @@ module ActionController #:nodoc:
|
||||
|
||||
key = fragment_cache_key(key)
|
||||
instrument_fragment_cache :write_fragment, key do
|
||||
content = content.html_safe.to_str if content.respond_to?(:html_safe)
|
||||
content = content.to_str
|
||||
cache_store.write(key, content, options)
|
||||
end
|
||||
content
|
||||
|
||||
@@ -50,11 +50,11 @@ module ActionDispatch
|
||||
# Only this middleware cares about RoutingError. So, let's just raise
|
||||
# it here.
|
||||
if headers['X-Cascade'] == 'pass'
|
||||
exception = ActionController::RoutingError.new("No route matches #{env['PATH_INFO'].inspect}")
|
||||
raise ActionController::RoutingError, "No route matches #{env['PATH_INFO'].inspect}"
|
||||
end
|
||||
rescue Exception => exception
|
||||
raise exception if env['action_dispatch.show_exceptions'] == false
|
||||
end
|
||||
raise exception if env['action_dispatch.show_exceptions'] == false
|
||||
|
||||
exception ? render_exception(env, exception) : [status, headers, body]
|
||||
end
|
||||
|
||||
@@ -450,7 +450,7 @@ module ActionDispatch
|
||||
end
|
||||
|
||||
def raise_routing_error
|
||||
raise ActionController::RoutingError.new("No route matches #{options.inspect}")
|
||||
raise ActionController::RoutingError, "No route matches #{options.inspect}"
|
||||
end
|
||||
|
||||
def different_controller?
|
||||
|
||||
@@ -156,10 +156,8 @@ module ActionView
|
||||
# The instance of ActionView::Base that is used by +render+.
|
||||
def view
|
||||
@view ||= begin
|
||||
view = ActionView::Base.new(ActionController::Base.view_paths, {}, @controller)
|
||||
view = @controller.view_context
|
||||
view.singleton_class.send :include, _helpers
|
||||
view.singleton_class.send :include, @controller._routes.url_helpers
|
||||
view.singleton_class.send :delegate, :alert, :notice, :to => "request.flash"
|
||||
view.extend(Locals)
|
||||
view.locals = self.locals
|
||||
view.output_buffer = self.output_buffer
|
||||
|
||||
@@ -116,6 +116,27 @@ module ActionView
|
||||
end
|
||||
end
|
||||
|
||||
class ControllerHelperMethod < ActionView::TestCase
|
||||
module SomeHelper
|
||||
def some_method
|
||||
render :partial => 'test/from_helper'
|
||||
end
|
||||
end
|
||||
|
||||
helper SomeHelper
|
||||
|
||||
test "can call a helper method defined on the current controller from a helper" do
|
||||
@controller.singleton_class.class_eval <<-EOF, __FILE__, __LINE__ + 1
|
||||
def render_from_helper
|
||||
'controller_helper_method'
|
||||
end
|
||||
EOF
|
||||
@controller.class.helper_method :render_from_helper
|
||||
|
||||
assert_equal 'controller_helper_method', some_method
|
||||
end
|
||||
end
|
||||
|
||||
class AssignsTest < ActionView::TestCase
|
||||
setup do
|
||||
ActiveSupport::Deprecation.stubs(:warn)
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace :test do
|
||||
end
|
||||
end
|
||||
|
||||
%w( mysql mysql2 postgresql sqlite3 firebird db2 oracle sybase openbase frontbase jdbcmysql jdbcpostgresql jdbcsqlite3 jdbcderby jdbch2 jdbchsqldb ).each do |adapter|
|
||||
%w( mysql mysql2 postgresql sqlite3 sqlite3_mem firebird db2 oracle sybase openbase frontbase jdbcmysql jdbcpostgresql jdbcsqlite3 jdbcderby jdbch2 jdbchsqldb ).each do |adapter|
|
||||
Rake::TestTask.new("test_#{adapter}") { |t|
|
||||
connection_path = "test/connections/#{adapter =~ /jdbc/ ? 'jdbc' : 'native'}_#{adapter}"
|
||||
adapter_short = adapter == 'db2' ? adapter : adapter[/^[a-z0-9]+/]
|
||||
|
||||
@@ -126,21 +126,21 @@ module ActiveRecord
|
||||
parent_records.each do |parent_record|
|
||||
association_proxy = parent_record.send(reflection_name)
|
||||
association_proxy.loaded
|
||||
association_proxy.target.push(*Array.wrap(associated_record))
|
||||
association_proxy.target.concat(Array.wrap(associated_record))
|
||||
association_proxy.send(:set_inverse_instance, associated_record)
|
||||
end
|
||||
end
|
||||
|
||||
def add_preloaded_record_to_collection(parent_records, reflection_name, associated_record)
|
||||
parent_records.each do |parent_record|
|
||||
parent_record.send("set_#{reflection_name}_target", associated_record)
|
||||
parent_record.send(:association_proxy, reflection_name).target = associated_record
|
||||
end
|
||||
end
|
||||
|
||||
def set_association_collection_records(id_to_record_map, reflection_name, associated_records, key)
|
||||
def set_association_collection_records(id_to_parent_map, reflection_name, associated_records, key)
|
||||
associated_records.each do |associated_record|
|
||||
mapped_records = id_to_record_map[associated_record[key].to_s]
|
||||
add_preloaded_records_to_collection(mapped_records, reflection_name, associated_record)
|
||||
parent_records = id_to_parent_map[associated_record[key].to_s]
|
||||
add_preloaded_records_to_collection(parent_records, reflection_name, associated_record)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -158,14 +158,17 @@ module ActiveRecord
|
||||
seen_keys[seen_key] = true
|
||||
mapped_records = id_to_record_map[seen_key]
|
||||
mapped_records.each do |mapped_record|
|
||||
association_proxy = mapped_record.send("set_#{reflection_name}_target", associated_record)
|
||||
association_proxy = mapped_record.send(:association_proxy, reflection_name)
|
||||
association_proxy.target = associated_record
|
||||
association_proxy.send(:set_inverse_instance, associated_record)
|
||||
end
|
||||
end
|
||||
|
||||
id_to_record_map.each do |id, records|
|
||||
next if seen_keys.include?(id.to_s)
|
||||
records.each {|record| record.send("set_#{reflection_name}_target", nil) }
|
||||
records.each do |record|
|
||||
record.send(:association_proxy, reflection_name).target = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -196,7 +199,6 @@ module ActiveRecord
|
||||
|
||||
right = Arel::Table.new(options[:join_table]).alias('t0')
|
||||
|
||||
|
||||
join_condition = left[reflection.klass.primary_key].eq(
|
||||
right[reflection.association_foreign_key])
|
||||
|
||||
@@ -218,24 +220,35 @@ module ActiveRecord
|
||||
|
||||
custom_conditions = append_conditions(reflection, preload_options)
|
||||
|
||||
all_associated_records = associated_records(ids) do |some_ids|
|
||||
klass = associated_records_proxy.klass
|
||||
|
||||
associated_records(ids) { |some_ids|
|
||||
method = in_or_equal(some_ids)
|
||||
conditions = right[reflection.foreign_key].send(*method)
|
||||
conditions = custom_conditions.inject(conditions) do |ast, cond|
|
||||
ast.and cond
|
||||
end
|
||||
|
||||
associated_records_proxy.where(conditions).to_a
|
||||
end
|
||||
|
||||
set_association_collection_records(id_to_record_map, reflection.name, all_associated_records, 'the_parent_record_id')
|
||||
relation = associated_records_proxy.where(conditions)
|
||||
klass.connection.select_all(relation.arel.to_sql, 'SQL', relation.bind_values)
|
||||
}.map! { |row|
|
||||
parent_records = id_to_record_map[row['the_parent_record_id'].to_s]
|
||||
associated_record = klass.instantiate row
|
||||
add_preloaded_records_to_collection(
|
||||
parent_records, reflection.name, associated_record)
|
||||
associated_record
|
||||
}
|
||||
end
|
||||
|
||||
def preload_has_one_association(records, reflection, preload_options={})
|
||||
return if records.first.send("loaded_#{reflection.name}?")
|
||||
return if records.first.send(:association_proxy, reflection.name).loaded?
|
||||
id_to_record_map, ids = construct_id_map(records, reflection.options[:primary_key])
|
||||
options = reflection.options
|
||||
records.each {|record| record.send("set_#{reflection.name}_target", nil)}
|
||||
|
||||
records.each do |record|
|
||||
record.send(:association_proxy, reflection.name).target = nil
|
||||
end
|
||||
|
||||
if options[:through]
|
||||
through_records = preload_through_records(records, reflection, options[:through])
|
||||
|
||||
@@ -317,7 +330,7 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
def preload_belongs_to_association(records, reflection, preload_options={})
|
||||
return if records.first.send("loaded_#{reflection.name}?")
|
||||
return if records.first.send(:association_proxy, reflection.name).loaded?
|
||||
options = reflection.options
|
||||
|
||||
klasses_and_ids = {}
|
||||
@@ -415,7 +428,7 @@ module ActiveRecord
|
||||
in_clause_length = connection.in_clause_length || ids.size
|
||||
records = []
|
||||
ids.each_slice(in_clause_length) do |some_ids|
|
||||
records += yield(some_ids)
|
||||
records.concat yield(some_ids)
|
||||
end
|
||||
records
|
||||
end
|
||||
|
||||
@@ -137,6 +137,22 @@ module ActiveRecord
|
||||
# :nodoc:
|
||||
attr_reader :association_cache
|
||||
|
||||
protected
|
||||
|
||||
# Returns the proxy for the given association name, instantiating it if it doesn't
|
||||
# already exist
|
||||
def association_proxy(name)
|
||||
association = association_instance_get(name)
|
||||
|
||||
if association.nil?
|
||||
reflection = self.class.reflect_on_association(name)
|
||||
association = reflection.proxy_class.new(self, reflection)
|
||||
association_instance_set(name, association)
|
||||
end
|
||||
|
||||
association
|
||||
end
|
||||
|
||||
private
|
||||
# Returns the specified association instance if it responds to :loaded?, nil otherwise.
|
||||
def association_instance_get(name)
|
||||
@@ -332,26 +348,31 @@ module ActiveRecord
|
||||
# === One-to-one associations
|
||||
#
|
||||
# * Assigning an object to a +has_one+ association automatically saves that object and
|
||||
# the object being replaced (if there is one), in order to update their primary
|
||||
# keys - except if the parent object is unsaved (<tt>new_record? == true</tt>).
|
||||
# * If either of these saves fail (due to one of the objects being invalid) the assignment
|
||||
# statement returns +false+ and the assignment is cancelled.
|
||||
# the object being replaced (if there is one), in order to update their foreign
|
||||
# keys - except if the parent object is unsaved (<tt>new_record? == true</tt>).
|
||||
# * If either of these saves fail (due to one of the objects being invalid), an
|
||||
# <tt>ActiveRecord::RecordNotSaved</tt> exception is raised and the assignment is
|
||||
# cancelled.
|
||||
# * If you wish to assign an object to a +has_one+ association without saving it,
|
||||
# use the <tt>association.build</tt> method (documented below).
|
||||
# use the <tt>build_association</tt> method (documented below). The object being
|
||||
# replaced will still be saved to update its foreign key.
|
||||
# * Assigning an object to a +belongs_to+ association does not save the object, since
|
||||
# the foreign key field belongs on the parent. It does not save the parent either.
|
||||
# the foreign key field belongs on the parent. It does not save the parent either.
|
||||
#
|
||||
# === Collections
|
||||
#
|
||||
# * Adding an object to a collection (+has_many+ or +has_and_belongs_to_many+) automatically
|
||||
# saves that object, except if the parent object (the owner of the collection) is not yet
|
||||
# stored in the database.
|
||||
# saves that object, except if the parent object (the owner of the collection) is not yet
|
||||
# stored in the database.
|
||||
# * If saving any of the objects being added to a collection (via <tt>push</tt> or similar)
|
||||
# fails, then <tt>push</tt> returns +false+.
|
||||
# fails, then <tt>push</tt> returns +false+.
|
||||
# * If saving fails while replacing the collection (via <tt>association=</tt>), an
|
||||
# <tt>ActiveRecord::RecordNotSaved</tt> exception is raised and the assignment is
|
||||
# cancelled.
|
||||
# * You can add an object to a collection without automatically saving it by using the
|
||||
# <tt>collection.build</tt> method (documented below).
|
||||
# <tt>collection.build</tt> method (documented below).
|
||||
# * All unsaved (<tt>new_record? == true</tt>) members of the collection are automatically
|
||||
# saved when the parent is saved.
|
||||
# saved when the parent is saved.
|
||||
#
|
||||
# === Association callbacks
|
||||
#
|
||||
@@ -998,12 +1019,7 @@ module ActiveRecord
|
||||
reflection = create_has_many_reflection(association_id, options, &extension)
|
||||
configure_dependency_for_has_many(reflection)
|
||||
add_association_callbacks(reflection.name, reflection.options)
|
||||
|
||||
if options[:through]
|
||||
collection_accessor_methods(reflection, HasManyThroughAssociation)
|
||||
else
|
||||
collection_accessor_methods(reflection, HasManyAssociation)
|
||||
end
|
||||
collection_accessor_methods(reflection)
|
||||
end
|
||||
|
||||
# Specifies a one-to-one association with another class. This method should only be used
|
||||
@@ -1021,8 +1037,7 @@ module ActiveRecord
|
||||
# [build_association(attributes = {})]
|
||||
# Returns a new object of the associated type that has been instantiated
|
||||
# with +attributes+ and linked to this object through a foreign key, but has not
|
||||
# yet been saved. <b>Note:</b> This ONLY works if an association already exists.
|
||||
# It will NOT work if the association is +nil+.
|
||||
# yet been saved.
|
||||
# [create_association(attributes = {})]
|
||||
# Returns a new object of the associated type that has been instantiated
|
||||
# with +attributes+, linked to this object through a foreign key, and that
|
||||
@@ -1115,14 +1130,12 @@ module ActiveRecord
|
||||
def has_one(association_id, options = {})
|
||||
if options[:through]
|
||||
reflection = create_has_one_through_reflection(association_id, options)
|
||||
association_accessor_methods(reflection, ActiveRecord::Associations::HasOneThroughAssociation)
|
||||
else
|
||||
reflection = create_has_one_reflection(association_id, options)
|
||||
association_accessor_methods(reflection, HasOneAssociation)
|
||||
association_constructor_method(:build, reflection, HasOneAssociation)
|
||||
association_constructor_method(:create, reflection, HasOneAssociation)
|
||||
association_constructor_methods(reflection)
|
||||
configure_dependency_for_has_one(reflection)
|
||||
end
|
||||
association_accessor_methods(reflection)
|
||||
end
|
||||
|
||||
# Specifies a one-to-one association with another class. This method should only be used
|
||||
@@ -1239,12 +1252,10 @@ module ActiveRecord
|
||||
def belongs_to(association_id, options = {})
|
||||
reflection = create_belongs_to_reflection(association_id, options)
|
||||
|
||||
if reflection.options[:polymorphic]
|
||||
association_accessor_methods(reflection, BelongsToPolymorphicAssociation)
|
||||
else
|
||||
association_accessor_methods(reflection, BelongsToAssociation)
|
||||
association_constructor_method(:build, reflection, BelongsToAssociation)
|
||||
association_constructor_method(:create, reflection, BelongsToAssociation)
|
||||
association_accessor_methods(reflection)
|
||||
|
||||
unless reflection.options[:polymorphic]
|
||||
association_constructor_methods(reflection)
|
||||
end
|
||||
|
||||
add_counter_cache_callbacks(reflection) if options[:counter_cache]
|
||||
@@ -1429,7 +1440,7 @@ module ActiveRecord
|
||||
# 'DELETE FROM developers_projects WHERE active=1 AND developer_id = #{id} AND project_id = #{record.id}'
|
||||
def has_and_belongs_to_many(association_id, options = {}, &extension)
|
||||
reflection = create_has_and_belongs_to_many_reflection(association_id, options, &extension)
|
||||
collection_accessor_methods(reflection, HasAndBelongsToManyAssociation)
|
||||
collection_accessor_methods(reflection)
|
||||
|
||||
# Don't use a before_destroy callback since users' before_destroy
|
||||
# callbacks will be executed after the association is wiped out.
|
||||
@@ -1461,15 +1472,10 @@ module ActiveRecord
|
||||
table_name_prefix + join_table + table_name_suffix
|
||||
end
|
||||
|
||||
def association_accessor_methods(reflection, association_proxy_class)
|
||||
def association_accessor_methods(reflection)
|
||||
redefine_method(reflection.name) do |*params|
|
||||
force_reload = params.first unless params.empty?
|
||||
association = association_instance_get(reflection.name)
|
||||
|
||||
if association.nil?
|
||||
association = association_proxy_class.new(self, reflection)
|
||||
association_instance_set(reflection.name, association)
|
||||
end
|
||||
association = association_proxy(reflection.name)
|
||||
|
||||
if force_reload
|
||||
reflection.klass.uncached { association.reload }
|
||||
@@ -1480,40 +1486,15 @@ module ActiveRecord
|
||||
association.target.nil? ? nil : association
|
||||
end
|
||||
|
||||
redefine_method("loaded_#{reflection.name}?") do
|
||||
association = association_instance_get(reflection.name)
|
||||
association && association.loaded?
|
||||
end
|
||||
|
||||
redefine_method("#{reflection.name}=") do |record|
|
||||
association = association_instance_get(reflection.name)
|
||||
|
||||
if association.nil?
|
||||
association = association_proxy_class.new(self, reflection)
|
||||
association_instance_set(reflection.name, association)
|
||||
end
|
||||
|
||||
association.replace(record)
|
||||
association.target.nil? ? nil : association
|
||||
end
|
||||
|
||||
redefine_method("set_#{reflection.name}_target") do |target|
|
||||
association = association_proxy_class.new(self, reflection)
|
||||
association.target = target
|
||||
association.loaded
|
||||
association_instance_set(reflection.name, association)
|
||||
association_proxy(reflection.name).replace(record)
|
||||
end
|
||||
end
|
||||
|
||||
def collection_reader_method(reflection, association_proxy_class)
|
||||
def collection_reader_method(reflection)
|
||||
redefine_method(reflection.name) do |*params|
|
||||
force_reload = params.first unless params.empty?
|
||||
association = association_instance_get(reflection.name)
|
||||
|
||||
unless association
|
||||
association = association_proxy_class.new(self, reflection)
|
||||
association_instance_set(reflection.name, association)
|
||||
end
|
||||
association = association_proxy(reflection.name)
|
||||
|
||||
if force_reload
|
||||
reflection.klass.uncached { association.reload }
|
||||
@@ -1533,15 +1514,12 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
|
||||
def collection_accessor_methods(reflection, association_proxy_class, writer = true)
|
||||
collection_reader_method(reflection, association_proxy_class)
|
||||
def collection_accessor_methods(reflection, writer = true)
|
||||
collection_reader_method(reflection)
|
||||
|
||||
if writer
|
||||
redefine_method("#{reflection.name}=") do |new_value|
|
||||
# Loads proxy class instance (defined in collection_reader_method) if not already loaded
|
||||
association = send(reflection.name)
|
||||
association.replace(new_value)
|
||||
association
|
||||
association_proxy(reflection.name).replace(new_value)
|
||||
end
|
||||
|
||||
redefine_method("#{reflection.name.to_s.singularize}_ids=") do |new_value|
|
||||
@@ -1553,17 +1531,18 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
|
||||
def association_constructor_method(constructor, reflection, association_proxy_class)
|
||||
redefine_method("#{constructor}_#{reflection.name}") do |*params|
|
||||
attributes = params.first unless params.empty?
|
||||
association = association_instance_get(reflection.name)
|
||||
def association_constructor_methods(reflection)
|
||||
constructors = {
|
||||
"build_#{reflection.name}" => "build",
|
||||
"create_#{reflection.name}" => "create"
|
||||
}
|
||||
constructors["create_#{reflection.name}!"] = "create!" if reflection.macro == :has_one
|
||||
|
||||
unless association
|
||||
association = association_proxy_class.new(self, reflection)
|
||||
association_instance_set(reflection.name, association)
|
||||
constructors.each do |name, proxy_name|
|
||||
redefine_method(name) do |*params|
|
||||
attributes = params.first unless params.empty?
|
||||
association_proxy(reflection.name).send(proxy_name, attributes)
|
||||
end
|
||||
|
||||
association.send(constructor, attributes)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -314,7 +314,11 @@ module ActiveRecord
|
||||
|
||||
transaction do
|
||||
delete(@target - other_array)
|
||||
concat(other_array - @target)
|
||||
|
||||
unless concat(other_array - @target)
|
||||
raise RecordNotSaved, "Failed to replace #{@reflection.name} because one or more of the "
|
||||
"new records could not be saved."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -213,7 +213,8 @@ module ActiveRecord
|
||||
# Set the inverse association, if possible
|
||||
def set_inverse_instance(record)
|
||||
if record && invertible_for?(record)
|
||||
record.send("set_#{inverse_reflection_for(record).name}_target", @owner)
|
||||
inverse = record.send(:association_proxy, inverse_reflection_for(record).name)
|
||||
inverse.target = @owner
|
||||
end
|
||||
end
|
||||
|
||||
@@ -259,23 +260,6 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
# Forwards any missing method call to the \target.
|
||||
def method_missing(method, *args)
|
||||
if load_target
|
||||
unless @target.respond_to?(method)
|
||||
message = "undefined method `#{method.to_s}' for \"#{@target}\":#{@target.class.to_s}"
|
||||
raise NoMethodError, message
|
||||
end
|
||||
|
||||
if block_given?
|
||||
@target.send(method, *args) { |*block_args| yield(*block_args) }
|
||||
else
|
||||
@target.send(method, *args)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Loads the \target if needed and returns it.
|
||||
#
|
||||
# This method is abstract in the sense that it relies on +find_target+,
|
||||
@@ -299,6 +283,18 @@ module ActiveRecord
|
||||
reset
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Forwards any missing method call to the \target.
|
||||
def method_missing(method, *args, &block)
|
||||
if load_target
|
||||
return super unless @target.respond_to?(method)
|
||||
@target.send(method, *args, &block)
|
||||
end
|
||||
rescue NoMethodError => e
|
||||
raise e, e.message.sub(/ for #<.*$/, " via proxy for #{@target}")
|
||||
end
|
||||
|
||||
# Should be true if there is a foreign key present on the @owner which
|
||||
# references the target. This is used to determine whether we can load
|
||||
# the target if the @owner is currently a new record (and therefore
|
||||
|
||||
@@ -223,7 +223,8 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
def set_target_and_inverse(join_part, association, record)
|
||||
association_proxy = record.send("set_#{join_part.reflection.name}_target", association)
|
||||
association_proxy = record.send(:association_proxy, join_part.reflection.name)
|
||||
association_proxy.target = association
|
||||
association_proxy.send(:set_inverse_instance, association)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,7 +7,7 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
def create!(attributes = {})
|
||||
new_record(:create_association!, attributes)
|
||||
build(attributes).tap { |record| record.save! }
|
||||
end
|
||||
|
||||
def build(attributes = {})
|
||||
@@ -19,23 +19,25 @@ module ActiveRecord
|
||||
raise_on_type_mismatch(record) unless record.nil?
|
||||
load_target
|
||||
|
||||
if @target && @target != record
|
||||
remove_target(save && @reflection.options[:dependent])
|
||||
end
|
||||
@reflection.klass.transaction do
|
||||
if @target && @target != record
|
||||
remove_target!(@reflection.options[:dependent])
|
||||
end
|
||||
|
||||
if record
|
||||
set_owner_attributes(record)
|
||||
set_inverse_instance(record)
|
||||
if record
|
||||
set_inverse_instance(record)
|
||||
set_owner_attributes(record)
|
||||
|
||||
if @owner.persisted? && save && !record.save
|
||||
nullify_owner_attributes(record)
|
||||
set_owner_attributes(@target)
|
||||
raise RecordNotSaved, "Failed to save the new associated #{@reflection.name}."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@target = record
|
||||
loaded
|
||||
|
||||
if @owner.persisted? && record && save
|
||||
record.save && self
|
||||
else
|
||||
record && self
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
@@ -49,21 +51,32 @@ module ActiveRecord
|
||||
|
||||
alias creation_attributes construct_owner_attributes
|
||||
|
||||
# The reason that the save param for replace is false, if for create (not just build),
|
||||
# is because the setting of the foreign keys is actually handled by the scoping, and
|
||||
# so they are set straight away and do not need to be updated within replace.
|
||||
def new_record(method, attributes)
|
||||
record = scoped.scoping { @reflection.send(method, attributes) }
|
||||
replace(record, false)
|
||||
record
|
||||
end
|
||||
|
||||
def remove_target(method)
|
||||
case method
|
||||
when :delete, :destroy
|
||||
def remove_target!(method)
|
||||
if [:delete, :destroy].include?(method)
|
||||
@target.send(method)
|
||||
else
|
||||
@target[@reflection.foreign_key] = nil
|
||||
@target.save if @target.persisted? && @owner.persisted?
|
||||
nullify_owner_attributes(@target)
|
||||
|
||||
if @target.persisted? && @owner.persisted? && !@target.save
|
||||
set_owner_attributes(@target)
|
||||
raise RecordNotSaved, "Failed to remove the existing associated #{@reflection.name}. " +
|
||||
"The record failed to save when after its foreign key was set to nil."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def nullify_owner_attributes(record)
|
||||
record[@reflection.foreign_key] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,9 +13,8 @@ module ActiveRecord
|
||||
private
|
||||
|
||||
def create_through_record(new_value)
|
||||
proxy = @owner.send(@reflection.through_reflection.name) ||
|
||||
@owner.send(:association_instance_get, @reflection.through_reflection.name)
|
||||
record = proxy.target
|
||||
proxy = @owner.send(:association_proxy, @reflection.through_reflection.name)
|
||||
record = proxy.send(:load_target)
|
||||
|
||||
if record && !new_value
|
||||
record.destroy
|
||||
@@ -31,10 +30,6 @@ module ActiveRecord
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def find_target
|
||||
scoped.first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -880,6 +880,16 @@ module ActiveRecord #:nodoc:
|
||||
record
|
||||
end
|
||||
|
||||
|
||||
# Finder methods must instantiate through this method to work with the
|
||||
# single-table inheritance model that makes it possible to create
|
||||
# objects of different types from the same table.
|
||||
def instantiate(record) # :nodoc:
|
||||
model = find_sti_class(record[inheritance_column]).allocate
|
||||
model.init_with('attributes' => record)
|
||||
model
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def relation #:nodoc:
|
||||
@@ -892,15 +902,6 @@ module ActiveRecord #:nodoc:
|
||||
end
|
||||
end
|
||||
|
||||
# Finder methods must instantiate through this method to work with the
|
||||
# single-table inheritance model that makes it possible to create
|
||||
# objects of different types from the same table.
|
||||
def instantiate(record)
|
||||
model = find_sti_class(record[inheritance_column]).allocate
|
||||
model.init_with('attributes' => record)
|
||||
model
|
||||
end
|
||||
|
||||
def find_sti_class(type_name)
|
||||
if type_name.blank? || !columns_hash.include?(inheritance_column)
|
||||
self
|
||||
@@ -1577,7 +1578,7 @@ MSG
|
||||
# Returns true if the specified +attribute+ has been set by the user or by a database load and is neither
|
||||
# nil nor empty? (the latter only applies to objects that respond to empty?, most notably Strings).
|
||||
def attribute_present?(attribute)
|
||||
!read_attribute(attribute).blank?
|
||||
!_read_attribute(attribute).blank?
|
||||
end
|
||||
|
||||
# Returns the column object for the named attribute.
|
||||
|
||||
@@ -77,8 +77,8 @@ module ActiveRecord
|
||||
false
|
||||
end
|
||||
|
||||
# Does this adapter support savepoints? PostgreSQL and MySQL do, SQLite
|
||||
# does not.
|
||||
# Does this adapter support savepoints? PostgreSQL and MySQL do,
|
||||
# SQLite < 3.6.8 does not.
|
||||
def supports_savepoints?
|
||||
false
|
||||
end
|
||||
|
||||
@@ -62,6 +62,10 @@ module ActiveRecord
|
||||
sqlite_version >= '2.0.0'
|
||||
end
|
||||
|
||||
def supports_savepoints?
|
||||
sqlite_version >= '3.6.8'
|
||||
end
|
||||
|
||||
# Returns +true+ when the connection adapter supports prepared statement
|
||||
# caching, otherwise returns +false+
|
||||
def supports_statement_cache?
|
||||
@@ -189,6 +193,18 @@ module ActiveRecord
|
||||
exec_query(sql, name).rows
|
||||
end
|
||||
|
||||
def create_savepoint
|
||||
execute("SAVEPOINT #{current_savepoint_name}")
|
||||
end
|
||||
|
||||
def rollback_to_savepoint
|
||||
execute("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
|
||||
end
|
||||
|
||||
def release_savepoint
|
||||
execute("RELEASE SAVEPOINT #{current_savepoint_name}")
|
||||
end
|
||||
|
||||
def begin_db_transaction #:nodoc:
|
||||
@connection.transaction
|
||||
end
|
||||
|
||||
@@ -313,6 +313,31 @@ module ActiveRecord
|
||||
macro == :belongs_to
|
||||
end
|
||||
|
||||
def proxy_class
|
||||
case macro
|
||||
when :belongs_to
|
||||
if options[:polymorphic]
|
||||
Associations::BelongsToPolymorphicAssociation
|
||||
else
|
||||
Associations::BelongsToAssociation
|
||||
end
|
||||
when :has_and_belongs_to_many
|
||||
Associations::HasAndBelongsToManyAssociation
|
||||
when :has_many
|
||||
if options[:through]
|
||||
Associations::HasManyThroughAssociation
|
||||
else
|
||||
Associations::HasManyAssociation
|
||||
end
|
||||
when :has_one
|
||||
if options[:through]
|
||||
Associations::HasOneThroughAssociation
|
||||
else
|
||||
Associations::HasOneAssociation
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def derive_class_name
|
||||
class_name = name.to_s.camelize
|
||||
|
||||
@@ -282,15 +282,11 @@ module ActiveRecord
|
||||
end
|
||||
|
||||
def type_cast_calculated_value(value, column, operation = nil)
|
||||
if value.is_a?(String) || value.nil?
|
||||
case operation
|
||||
when 'count' then value.to_i
|
||||
when 'sum' then type_cast_using_column(value || '0', column)
|
||||
when 'average' then value.try(:to_d)
|
||||
else type_cast_using_column(value, column)
|
||||
end
|
||||
else
|
||||
type_cast_using_column(value, column)
|
||||
case operation
|
||||
when 'count' then value.to_i
|
||||
when 'sum' then type_cast_using_column(value || '0', column)
|
||||
when 'average' then value.try(:to_d)
|
||||
else type_cast_using_column(value, column)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ HEADER
|
||||
|
||||
# first dump primary key column
|
||||
if @connection.respond_to?(:pk_and_sequence_for)
|
||||
pk, pk_seq = @connection.pk_and_sequence_for(table)
|
||||
pk, _ = @connection.pk_and_sequence_for(table)
|
||||
elsif @connection.respond_to?(:primary_key)
|
||||
pk = @connection.primary_key(table)
|
||||
end
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
require "cases/helper"
|
||||
|
||||
module ActiveRecord
|
||||
module Associations
|
||||
class AsssociationProxyTest < ActiveRecord::TestCase
|
||||
class FakeOwner
|
||||
attr_accessor :new_record
|
||||
alias :new_record? :new_record
|
||||
|
||||
def initialize
|
||||
@new_record = false
|
||||
end
|
||||
end
|
||||
|
||||
class FakeReflection < Struct.new(:options, :klass)
|
||||
def initialize options = {}, klass = nil
|
||||
super
|
||||
end
|
||||
|
||||
def check_validity!
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
class FakeTarget
|
||||
end
|
||||
|
||||
class FakeTargetProxy < AssociationProxy
|
||||
def association_scope
|
||||
true
|
||||
end
|
||||
|
||||
def find_target
|
||||
FakeTarget.new
|
||||
end
|
||||
end
|
||||
|
||||
def test_method_missing_error
|
||||
reflection = FakeReflection.new({}, Object.new)
|
||||
owner = FakeOwner.new
|
||||
proxy = FakeTargetProxy.new(owner, reflection)
|
||||
|
||||
exception = assert_raises(NoMethodError) do
|
||||
proxy.omg
|
||||
end
|
||||
|
||||
assert_match('omg', exception.message)
|
||||
assert_match(FakeTarget.name, exception.message)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -146,6 +146,15 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
||||
assert_not_nil Company.find(3).firm_with_condition, "Microsoft should have a firm"
|
||||
end
|
||||
|
||||
def test_with_polymorphic_and_condition
|
||||
sponsor = Sponsor.create
|
||||
member = Member.create :name => "Bert"
|
||||
sponsor.sponsorable = member
|
||||
|
||||
assert_equal member, sponsor.sponsorable
|
||||
assert_nil sponsor.sponsorable_with_conditions
|
||||
end
|
||||
|
||||
def test_with_select
|
||||
assert_equal Company.find(2).firm_with_select.attributes.size, 1
|
||||
assert_equal Company.find(2, :include => :firm_with_select ).firm_with_select.attributes.size, 1
|
||||
|
||||
@@ -975,6 +975,19 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
||||
assert !firm.clients.include?(:first_client)
|
||||
end
|
||||
|
||||
def test_replace_failure
|
||||
firm = companies(:first_firm)
|
||||
account = Account.new
|
||||
orig_accounts = firm.accounts.to_a
|
||||
|
||||
assert !account.valid?
|
||||
assert !orig_accounts.empty?
|
||||
assert_raise ActiveRecord::RecordNotSaved do
|
||||
firm.accounts = [account]
|
||||
end
|
||||
assert_equal orig_accounts, firm.accounts
|
||||
end
|
||||
|
||||
def test_get_ids
|
||||
assert_equal [companies(:first_client).id, companies(:second_client).id], companies(:first_firm).client_ids
|
||||
end
|
||||
|
||||
@@ -2,9 +2,12 @@ require "cases/helper"
|
||||
require 'models/developer'
|
||||
require 'models/project'
|
||||
require 'models/company'
|
||||
require 'models/ship'
|
||||
require 'models/pirate'
|
||||
|
||||
class HasOneAssociationsTest < ActiveRecord::TestCase
|
||||
fixtures :accounts, :companies, :developers, :projects, :developers_projects
|
||||
self.use_transactional_fixtures = false unless supports_savepoints?
|
||||
fixtures :accounts, :companies, :developers, :projects, :developers_projects, :ships, :pirates
|
||||
|
||||
def setup
|
||||
Account.destroyed_account_ids.clear
|
||||
@@ -91,18 +94,18 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
|
||||
def test_nullification_on_association_change
|
||||
firm = companies(:rails_core)
|
||||
old_account_id = firm.account.id
|
||||
firm.account = Account.new
|
||||
firm.account = Account.new(:credit_limit => 5)
|
||||
# account is dependent with nullify, therefore its firm_id should be nil
|
||||
assert_nil Account.find(old_account_id).firm_id
|
||||
end
|
||||
|
||||
def test_association_change_calls_delete
|
||||
companies(:first_firm).deletable_account = Account.new
|
||||
companies(:first_firm).deletable_account = Account.new(:credit_limit => 5)
|
||||
assert_equal [], Account.destroyed_account_ids[companies(:first_firm).id]
|
||||
end
|
||||
|
||||
def test_association_change_calls_destroy
|
||||
companies(:first_firm).account = Account.new
|
||||
companies(:first_firm).account = Account.new(:credit_limit => 5)
|
||||
assert_equal [companies(:first_firm).id], Account.destroyed_account_ids[companies(:first_firm).id]
|
||||
end
|
||||
|
||||
@@ -164,21 +167,30 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
|
||||
assert_equal account, firm.account
|
||||
end
|
||||
|
||||
def test_build_association_twice_without_saving_affects_nothing
|
||||
count_of_account = Account.count
|
||||
firm = Firm.find(:first)
|
||||
firm.build_account("credit_limit" => 1000)
|
||||
firm.build_account("credit_limit" => 2000)
|
||||
|
||||
assert_equal count_of_account, Account.count
|
||||
end
|
||||
|
||||
def test_create_association
|
||||
firm = Firm.create(:name => "GlobalMegaCorp")
|
||||
account = firm.create_account(:credit_limit => 1000)
|
||||
assert_equal account, firm.reload.account
|
||||
end
|
||||
|
||||
def test_create_association_with_bang
|
||||
firm = Firm.create(:name => "GlobalMegaCorp")
|
||||
account = firm.create_account!(:credit_limit => 1000)
|
||||
assert_equal account, firm.reload.account
|
||||
end
|
||||
|
||||
def test_create_association_with_bang_failing
|
||||
firm = Firm.create(:name => "GlobalMegaCorp")
|
||||
assert_raise ActiveRecord::RecordInvalid do
|
||||
firm.create_account!
|
||||
end
|
||||
account = firm.account
|
||||
assert_not_nil account
|
||||
account.credit_limit = 5
|
||||
account.save
|
||||
assert_equal account, firm.reload.account
|
||||
end
|
||||
|
||||
def test_build
|
||||
firm = Firm.new("name" => "GlobalMegaCorp")
|
||||
firm.save
|
||||
@@ -189,17 +201,6 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
|
||||
assert_equal account, firm.account
|
||||
end
|
||||
|
||||
def test_failing_build_association
|
||||
firm = Firm.new("name" => "GlobalMegaCorp")
|
||||
firm.save
|
||||
|
||||
firm.account = account = Account.new
|
||||
assert_equal account, firm.account
|
||||
assert !account.save
|
||||
assert_equal account, firm.account
|
||||
assert_equal ["can't be empty"], account.errors["credit_limit"]
|
||||
end
|
||||
|
||||
def test_create
|
||||
firm = Firm.new("name" => "GlobalMegaCorp")
|
||||
firm.save
|
||||
@@ -293,4 +294,51 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
|
||||
new_account = companies(:first_firm).build_account(:firm_name => 'Account')
|
||||
assert_equal new_account.firm_name, "Account"
|
||||
end
|
||||
|
||||
def test_creation_failure_without_dependent_option
|
||||
pirate = pirates(:blackbeard)
|
||||
orig_ship = pirate.ship.target
|
||||
|
||||
assert_equal ships(:black_pearl), orig_ship
|
||||
new_ship = pirate.create_ship
|
||||
assert_not_equal ships(:black_pearl), new_ship
|
||||
assert_equal new_ship, pirate.ship
|
||||
assert new_ship.new_record?
|
||||
assert_nil orig_ship.pirate_id
|
||||
assert !orig_ship.changed? # check it was saved
|
||||
end
|
||||
|
||||
def test_creation_failure_with_dependent_option
|
||||
pirate = pirates(:blackbeard).becomes(DestructivePirate)
|
||||
orig_ship = pirate.dependent_ship.target
|
||||
|
||||
new_ship = pirate.create_dependent_ship
|
||||
assert new_ship.new_record?
|
||||
assert orig_ship.destroyed?
|
||||
end
|
||||
|
||||
def test_replacement_failure_due_to_existing_record_should_raise_error
|
||||
pirate = pirates(:blackbeard)
|
||||
pirate.ship.name = nil
|
||||
|
||||
assert !pirate.ship.valid?
|
||||
assert_raise(ActiveRecord::RecordNotSaved) do
|
||||
pirate.ship = ships(:interceptor)
|
||||
end
|
||||
assert_equal ships(:black_pearl), pirate.ship
|
||||
assert_equal pirate.id, pirate.ship.pirate_id
|
||||
end
|
||||
|
||||
def test_replacement_failure_due_to_new_record_should_raise_error
|
||||
pirate = pirates(:blackbeard)
|
||||
new_ship = Ship.new
|
||||
|
||||
assert_raise(ActiveRecord::RecordNotSaved) do
|
||||
pirate.ship = new_ship
|
||||
end
|
||||
assert_equal ships(:black_pearl), pirate.ship
|
||||
assert_equal pirate.id, pirate.ship.pirate_id
|
||||
assert_equal pirate.id, ships(:black_pearl).reload.pirate_id
|
||||
assert_nil new_ship.pirate_id
|
||||
end
|
||||
end
|
||||
|
||||
@@ -197,7 +197,7 @@ class HasOneThroughAssociationsTest < ActiveRecord::TestCase
|
||||
MemberDetail.find(:all, :include => :member_type)
|
||||
end
|
||||
@new_detail = @member_details[0]
|
||||
assert @new_detail.loaded_member_type?
|
||||
assert @new_detail.send(:association_proxy, :member_type).loaded?
|
||||
assert_not_nil assert_no_queries { @new_detail.member_type }
|
||||
end
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@ require 'models/book'
|
||||
require 'models/citation'
|
||||
|
||||
class AssociationsJoinModelTest < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
self.use_transactional_fixtures = false unless supports_savepoints?
|
||||
|
||||
fixtures :posts, :authors, :categories, :categorizations, :comments, :tags, :taggings, :author_favorites, :vertices, :items, :books,
|
||||
# Reload edges table from fixtures as otherwise repeated test was failing
|
||||
:edges
|
||||
@@ -522,7 +523,7 @@ class AssociationsJoinModelTest < ActiveRecord::TestCase
|
||||
|
||||
def test_has_many_through_collection_size_uses_counter_cache_if_it_exists
|
||||
author = authors(:david)
|
||||
author.stubs(:read_attribute).with('comments_count').returns(100)
|
||||
author.stubs(:_read_attribute).with('comments_count').returns(100)
|
||||
assert_equal 100, author.comments.size
|
||||
assert !author.comments.loaded?
|
||||
end
|
||||
|
||||
@@ -90,7 +90,7 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
|
||||
firm = Firm.find(:first)
|
||||
assert firm.valid?
|
||||
|
||||
firm.account = Account.new
|
||||
firm.build_account
|
||||
|
||||
assert !firm.account.valid?
|
||||
assert !firm.valid?
|
||||
@@ -102,7 +102,7 @@ class TestDefaultAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCas
|
||||
firm = Firm.find(:first)
|
||||
assert firm.valid?
|
||||
|
||||
firm.unvalidated_account = Account.new
|
||||
firm.build_unvalidated_account
|
||||
|
||||
assert !firm.unvalidated_account.valid?
|
||||
assert firm.valid?
|
||||
@@ -572,7 +572,7 @@ class TestDefaultAutosaveAssociationOnNewRecord < ActiveRecord::TestCase
|
||||
end
|
||||
|
||||
class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
self.use_transactional_fixtures = false unless supports_savepoints?
|
||||
|
||||
def setup
|
||||
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
|
||||
@@ -797,7 +797,7 @@ class TestDestroyAsPartOfAutosaveAssociation < ActiveRecord::TestCase
|
||||
end
|
||||
|
||||
class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
self.use_transactional_fixtures = false unless supports_savepoints?
|
||||
|
||||
def setup
|
||||
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
|
||||
@@ -917,7 +917,7 @@ class TestAutosaveAssociationOnAHasOneAssociation < ActiveRecord::TestCase
|
||||
end
|
||||
|
||||
class TestAutosaveAssociationOnABelongsToAssociation < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
self.use_transactional_fixtures = false unless supports_savepoints?
|
||||
|
||||
def setup
|
||||
@ship = Ship.create(:name => 'Nights Dirty Lightning')
|
||||
@@ -1164,7 +1164,7 @@ module AutosaveAssociationOnACollectionAssociationTests
|
||||
end
|
||||
|
||||
class TestAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
self.use_transactional_fixtures = false unless supports_savepoints?
|
||||
|
||||
def setup
|
||||
@association_name = :birds
|
||||
@@ -1178,7 +1178,7 @@ class TestAutosaveAssociationOnAHasManyAssociation < ActiveRecord::TestCase
|
||||
end
|
||||
|
||||
class TestAutosaveAssociationOnAHasAndBelongsToManyAssociation < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
self.use_transactional_fixtures = false unless supports_savepoints?
|
||||
|
||||
def setup
|
||||
@association_name = :parrots
|
||||
@@ -1193,7 +1193,7 @@ class TestAutosaveAssociationOnAHasAndBelongsToManyAssociation < ActiveRecord::T
|
||||
end
|
||||
|
||||
class TestAutosaveAssociationValidationsOnAHasManyAssociation < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
self.use_transactional_fixtures = false unless supports_savepoints?
|
||||
|
||||
def setup
|
||||
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
|
||||
@@ -1209,7 +1209,7 @@ class TestAutosaveAssociationValidationsOnAHasManyAssociation < ActiveRecord::Te
|
||||
end
|
||||
|
||||
class TestAutosaveAssociationValidationsOnAHasOneAssociation < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
self.use_transactional_fixtures = false unless supports_savepoints?
|
||||
|
||||
def setup
|
||||
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
|
||||
@@ -1230,7 +1230,7 @@ class TestAutosaveAssociationValidationsOnAHasOneAssociation < ActiveRecord::Tes
|
||||
end
|
||||
|
||||
class TestAutosaveAssociationValidationsOnABelongsToAssociation < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
self.use_transactional_fixtures = false unless supports_savepoints?
|
||||
|
||||
def setup
|
||||
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
|
||||
@@ -1250,7 +1250,7 @@ class TestAutosaveAssociationValidationsOnABelongsToAssociation < ActiveRecord::
|
||||
end
|
||||
|
||||
class TestAutosaveAssociationValidationsOnAHABTMAssociation < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
self.use_transactional_fixtures = false unless supports_savepoints?
|
||||
|
||||
def setup
|
||||
@pirate = Pirate.create(:catchphrase => "Don' botharrr talkin' like one, savvy?")
|
||||
@@ -1272,7 +1272,7 @@ class TestAutosaveAssociationValidationsOnAHABTMAssociation < ActiveRecord::Test
|
||||
end
|
||||
|
||||
class TestAutosaveAssociationValidationMethodsGeneration < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
self.use_transactional_fixtures = false unless supports_savepoints?
|
||||
|
||||
def setup
|
||||
@pirate = Pirate.new
|
||||
|
||||
@@ -23,6 +23,11 @@ class CalculationsTest < ActiveRecord::TestCase
|
||||
assert_equal 53.0, value
|
||||
end
|
||||
|
||||
def test_should_return_decimal_average_of_integer_field
|
||||
value = Account.average(:id)
|
||||
assert_equal 3.5, value
|
||||
end
|
||||
|
||||
def test_should_return_nil_as_average
|
||||
assert_nil NumericData.average(:bank_balance)
|
||||
end
|
||||
|
||||
@@ -26,6 +26,15 @@ def current_adapter?(*types)
|
||||
end
|
||||
end
|
||||
|
||||
def in_memory_db?
|
||||
current_adapter?(:SQLiteAdapter) &&
|
||||
ActiveRecord::Base.connection_pool.spec.config[:database] == ":memory:"
|
||||
end
|
||||
|
||||
def supports_savepoints?
|
||||
ActiveRecord::Base.connection.supports_savepoints?
|
||||
end
|
||||
|
||||
def with_env_tz(new_tz = 'US/Eastern')
|
||||
old_tz, ENV['TZ'] = ENV['TZ'], new_tz
|
||||
yield
|
||||
@@ -100,11 +109,11 @@ class ActiveSupport::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
# silence verbose schema loading
|
||||
original_stdout = $stdout
|
||||
$stdout = StringIO.new
|
||||
def load_schema
|
||||
# silence verbose schema loading
|
||||
original_stdout = $stdout
|
||||
$stdout = StringIO.new
|
||||
|
||||
begin
|
||||
adapter_name = ActiveRecord::Base.connection.adapter_name.downcase
|
||||
adapter_specific_schema_file = SCHEMA_ROOT + "/#{adapter_name}_specific_schema.rb"
|
||||
|
||||
@@ -117,6 +126,8 @@ ensure
|
||||
$stdout = original_stdout
|
||||
end
|
||||
|
||||
load_schema
|
||||
|
||||
class << Time
|
||||
unless method_defined? :now_before_time_travel
|
||||
alias_method :now_before_time_travel, :now
|
||||
@@ -133,4 +144,3 @@ class << Time
|
||||
@now = nil
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -19,11 +19,6 @@ end
|
||||
class OptimisticLockingTest < ActiveRecord::TestCase
|
||||
fixtures :people, :legacy_things, :references
|
||||
|
||||
# need to disable transactional fixtures, because otherwise the sqlite3
|
||||
# adapter (at least) chokes when we try and change the schema in the middle
|
||||
# of a test (see test_increment_counter_*).
|
||||
self.use_transactional_fixtures = false
|
||||
|
||||
def test_lock_existing
|
||||
p1 = Person.find(1)
|
||||
p2 = Person.find(1)
|
||||
@@ -152,6 +147,33 @@ class OptimisticLockingTest < ActiveRecord::TestCase
|
||||
assert_equal "unchangeable name", p.first_name
|
||||
end
|
||||
|
||||
def test_quote_table_name
|
||||
ref = references(:michael_magician)
|
||||
ref.favourite = !ref.favourite
|
||||
assert ref.save
|
||||
end
|
||||
|
||||
# Useful for partial updates, don't only update the lock_version if there
|
||||
# is nothing else being updated.
|
||||
def test_update_without_attributes_does_not_only_update_lock_version
|
||||
assert_nothing_raised do
|
||||
p1 = Person.create!(:first_name => 'anika')
|
||||
lock_version = p1.lock_version
|
||||
p1.save
|
||||
p1.reload
|
||||
assert_equal lock_version, p1.lock_version
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class OptimisticLockingWithSchemaChangeTest < ActiveRecord::TestCase
|
||||
fixtures :people, :legacy_things, :references
|
||||
|
||||
# need to disable transactional fixtures, because otherwise the sqlite3
|
||||
# adapter (at least) chokes when we try and change the schema in the middle
|
||||
# of a test (see test_increment_counter_*).
|
||||
self.use_transactional_fixtures = false
|
||||
|
||||
{ :lock_version => Person, :custom_lock_version => LegacyThing }.each do |name, model|
|
||||
define_method("test_increment_counter_updates_#{name}") do
|
||||
counter_test model, 1 do |id|
|
||||
@@ -198,24 +220,6 @@ class OptimisticLockingTest < ActiveRecord::TestCase
|
||||
assert_raises(ActiveRecord::RecordNotFound) { LegacyThing.find(t.id) }
|
||||
end
|
||||
|
||||
def test_quote_table_name
|
||||
ref = references(:michael_magician)
|
||||
ref.favourite = !ref.favourite
|
||||
assert ref.save
|
||||
end
|
||||
|
||||
# Useful for partial updates, don't only update the lock_version if there
|
||||
# is nothing else being updated.
|
||||
def test_update_without_attributes_does_not_only_update_lock_version
|
||||
assert_nothing_raised do
|
||||
p1 = Person.create!(:first_name => 'anika')
|
||||
lock_version = p1.lock_version
|
||||
p1.save
|
||||
p1.reload
|
||||
assert_equal lock_version, p1.lock_version
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def add_counter_column_to(model, col='test_count')
|
||||
@@ -252,9 +256,9 @@ end
|
||||
|
||||
# TODO: The Sybase, and OpenBase adapters currently have no support for pessimistic locking
|
||||
|
||||
unless current_adapter?(:SybaseAdapter, :OpenBaseAdapter)
|
||||
unless current_adapter?(:SybaseAdapter, :OpenBaseAdapter) || in_memory_db?
|
||||
class PessimisticLockingTest < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
self.use_transactional_fixtures = false unless supports_savepoints?
|
||||
fixtures :people, :readers
|
||||
|
||||
def setup
|
||||
|
||||
@@ -14,7 +14,7 @@ if ActiveRecord::Base.connection.supports_migrations?
|
||||
class Reminder < ActiveRecord::Base; end
|
||||
|
||||
class ActiveRecord::Migration
|
||||
class <<self
|
||||
class << self
|
||||
attr_accessor :message_count
|
||||
end
|
||||
|
||||
@@ -2083,4 +2083,3 @@ if ActiveRecord::Base.connection.supports_migrations?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ require 'models/bird'
|
||||
require_dependency 'models/course'
|
||||
|
||||
class MultipleDbTest < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
self.use_transactional_fixtures = false unless supports_savepoints?
|
||||
|
||||
def setup
|
||||
@courses = create_fixtures("courses") { Course.retrieve_connection }
|
||||
|
||||
@@ -859,7 +859,7 @@ class TestNestedAttributesWithNonStandardPrimaryKeys < ActiveRecord::TestCase
|
||||
end
|
||||
|
||||
class TestHasOneAutosaveAssociationWhichItselfHasAutosaveAssociations < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
self.use_transactional_fixtures = false unless supports_savepoints?
|
||||
|
||||
def setup
|
||||
@pirate = Pirate.create!(:catchphrase => "My baby takes tha mornin' train!")
|
||||
@@ -899,7 +899,7 @@ class TestHasOneAutosaveAssociationWhichItselfHasAutosaveAssociations < ActiveRe
|
||||
end
|
||||
|
||||
class TestHasManyAutosaveAssociationWhichItselfHasAutosaveAssociations < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
self.use_transactional_fixtures = false unless supports_savepoints?
|
||||
|
||||
def setup
|
||||
@ship = Ship.create!(:name => "The good ship Dollypop")
|
||||
|
||||
@@ -137,4 +137,4 @@ class PooledConnectionsTest < ActiveRecord::TestCase
|
||||
def add_record(name)
|
||||
ActiveRecord::Base.connection_pool.with_connection { Project.create! :name => name }
|
||||
end
|
||||
end unless %w(FrontBase).include? ActiveRecord::Base.connection.adapter_name
|
||||
end unless current_adapter?(:FrontBase) || in_memory_db?
|
||||
|
||||
@@ -63,7 +63,7 @@ class QueryCacheTest < ActiveRecord::TestCase
|
||||
# Oracle adapter returns count() as Fixnum or Float
|
||||
if current_adapter?(:OracleAdapter)
|
||||
assert_kind_of Numeric, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
|
||||
elsif current_adapter?(:SQLite3Adapter) && SQLite3::Version::VERSION > '1.2.5' || current_adapter?(:Mysql2Adapter) || current_adapter?(:MysqlAdapter)
|
||||
elsif current_adapter?(:SQLite3Adapter) && SQLite3::VERSION > '1.2.5' || current_adapter?(:Mysql2Adapter) || current_adapter?(:MysqlAdapter)
|
||||
# Future versions of the sqlite3 adapter will return numeric
|
||||
assert_instance_of Fixnum,
|
||||
Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
|
||||
|
||||
@@ -5,7 +5,7 @@ require 'active_record/session_store'
|
||||
module ActiveRecord
|
||||
class SessionStore
|
||||
class SessionTest < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
self.use_transactional_fixtures = false unless supports_savepoints? && ActiveRecord::Base.connection.supports_ddl_transactions?
|
||||
|
||||
def setup
|
||||
super
|
||||
|
||||
@@ -4,7 +4,7 @@ class TestRecord < ActiveRecord::Base
|
||||
end
|
||||
|
||||
class TestUnconnectedAdapter < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
self.use_transactional_fixtures = false unless supports_savepoints?
|
||||
|
||||
def setup
|
||||
@underlying = ActiveRecord::Base.connection
|
||||
@@ -14,6 +14,7 @@ class TestUnconnectedAdapter < ActiveRecord::TestCase
|
||||
def teardown
|
||||
@underlying = nil
|
||||
ActiveRecord::Base.establish_connection(@specification)
|
||||
load_schema if in_memory_db?
|
||||
end
|
||||
|
||||
def test_connection_no_longer_established
|
||||
|
||||
@@ -6,19 +6,6 @@ require 'models/warehouse_thing'
|
||||
require 'models/guid'
|
||||
require 'models/event'
|
||||
|
||||
# The following methods in Topic are used in test_conditional_validation_*
|
||||
class Topic
|
||||
has_many :unique_replies, :dependent => :destroy, :foreign_key => "parent_id"
|
||||
has_many :silly_unique_replies, :dependent => :destroy, :foreign_key => "parent_id"
|
||||
end
|
||||
|
||||
class UniqueReply < Reply
|
||||
validates_uniqueness_of :content, :scope => 'parent_id'
|
||||
end
|
||||
|
||||
class SillyUniqueReply < UniqueReply
|
||||
end
|
||||
|
||||
class Wizard < ActiveRecord::Base
|
||||
self.abstract_class = true
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
print "Using native SQLite3\n"
|
||||
require_dependency 'models/course'
|
||||
require 'logger'
|
||||
ActiveRecord::Base.logger = Logger.new("debug.log")
|
||||
|
||||
class SqliteError < StandardError
|
||||
end
|
||||
|
||||
def make_connection(clazz, db_definitions_file)
|
||||
clazz.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
|
||||
File.read(SCHEMA_ROOT + "/#{db_definitions_file}").split(';').each do |command|
|
||||
clazz.connection.execute(command) unless command.strip.empty?
|
||||
end
|
||||
end
|
||||
|
||||
make_connection(ActiveRecord::Base, 'sqlite.sql')
|
||||
make_connection(Course, 'sqlite2.sql')
|
||||
load(SCHEMA_ROOT + "/schema.rb")
|
||||
@@ -0,0 +1,19 @@
|
||||
# This file connects to an in-memory SQLite3 database, which is a very fast way to run the tests.
|
||||
# The downside is that disconnect from the database results in the database effectively being
|
||||
# wiped. For this reason, pooled_connections_test.rb is disabled when using an in-memory database.
|
||||
|
||||
print "Using native SQLite3 (in memory)\n"
|
||||
require_dependency 'models/course'
|
||||
require 'logger'
|
||||
ActiveRecord::Base.logger = Logger.new("debug.log")
|
||||
|
||||
class SqliteError < StandardError
|
||||
end
|
||||
|
||||
def make_connection(clazz)
|
||||
ActiveRecord::Base.configurations = { clazz.name => { :adapter => 'sqlite3', :database => ':memory:' } }
|
||||
clazz.establish_connection(clazz.name)
|
||||
end
|
||||
|
||||
make_connection(ActiveRecord::Base)
|
||||
make_connection(Course)
|
||||
1
activerecord/test/fixtures/ships.yml
vendored
1
activerecord/test/fixtures/ships.yml
vendored
@@ -1,5 +1,6 @@
|
||||
black_pearl:
|
||||
name: "Black Pearl"
|
||||
pirate: blackbeard
|
||||
interceptor:
|
||||
id: 2
|
||||
name: "Interceptor"
|
||||
|
||||
@@ -78,3 +78,7 @@ class Pirate < ActiveRecord::Base
|
||||
ship_log << "#{callback}_#{record.class.name.downcase}_#{record.id || '<new>'}"
|
||||
end
|
||||
end
|
||||
|
||||
class DestructivePirate < Pirate
|
||||
has_one :dependent_ship, :class_name => 'Ship', :foreign_key => :pirate_id, :dependent => :destroy
|
||||
end
|
||||
|
||||
@@ -10,6 +10,13 @@ class Reply < Topic
|
||||
attr_accessible :title, :author_name, :author_email_address, :written_on, :content, :last_read, :parent_title
|
||||
end
|
||||
|
||||
class UniqueReply < Reply
|
||||
validates_uniqueness_of :content, :scope => 'parent_id'
|
||||
end
|
||||
|
||||
class SillyUniqueReply < UniqueReply
|
||||
end
|
||||
|
||||
class WrongReply < Reply
|
||||
validate :errors_on_empty_content
|
||||
validate :title_is_wrong_create, :on => :create
|
||||
|
||||
@@ -2,4 +2,6 @@ class Sponsor < ActiveRecord::Base
|
||||
belongs_to :sponsor_club, :class_name => "Club", :foreign_key => "club_id"
|
||||
belongs_to :sponsorable, :polymorphic => true
|
||||
belongs_to :thing, :polymorphic => true, :foreign_type => :sponsorable_type, :foreign_key => :sponsorable_id
|
||||
belongs_to :sponsorable_with_conditions, :polymorphic => true,
|
||||
:foreign_type => 'sponsorable_type', :foreign_key => 'sponsorable_id', :conditions => {:name => 'Ernie'}
|
||||
end
|
||||
|
||||
@@ -45,6 +45,10 @@ class Topic < ActiveRecord::Base
|
||||
|
||||
has_many :replies, :dependent => :destroy, :foreign_key => "parent_id"
|
||||
has_many :replies_with_primary_key, :class_name => "Reply", :dependent => :destroy, :primary_key => "title", :foreign_key => "parent_title"
|
||||
|
||||
has_many :unique_replies, :dependent => :destroy, :foreign_key => "parent_id"
|
||||
has_many :silly_unique_replies, :dependent => :destroy, :foreign_key => "parent_id"
|
||||
|
||||
serialize :content
|
||||
|
||||
before_create :default_written_on
|
||||
|
||||
@@ -18,6 +18,10 @@ class BigDecimal
|
||||
end
|
||||
end
|
||||
|
||||
def to_d
|
||||
self
|
||||
end
|
||||
|
||||
DEFAULT_STRING_FORMAT = 'F'
|
||||
def to_formatted_s(format = DEFAULT_STRING_FORMAT)
|
||||
_original_to_s(format)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
require 'date'
|
||||
require 'active_support/inflector'
|
||||
require 'active_support/inflector/methods'
|
||||
require 'active_support/core_ext/date/zones'
|
||||
|
||||
class Date
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'active_support/inflector'
|
||||
require 'active_support/inflector/methods'
|
||||
require 'active_support/core_ext/time/conversions'
|
||||
require 'active_support/core_ext/date_time/calculations'
|
||||
require 'active_support/values/time_zone'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'active_support/inflector'
|
||||
require 'active_support/inflector/methods'
|
||||
require 'active_support/core_ext/time/publicize_conversion_methods'
|
||||
require 'active_support/values/time_zone'
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'active_support/inflector'
|
||||
require 'active_support/inflector/methods'
|
||||
|
||||
module ActiveSupport
|
||||
module Deprecation
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
require 'abstract_unit'
|
||||
require 'bigdecimal'
|
||||
require 'active_support/core_ext/big_decimal'
|
||||
|
||||
class BigDecimalTest < Test::Unit::TestCase
|
||||
def test_to_yaml
|
||||
assert_equal("--- 100000.30020320320000000000000000000000000000001\n", BigDecimal.new('100000.30020320320000000000000000000000000000001').to_yaml)
|
||||
assert_equal("--- .Inf\n", BigDecimal.new('Infinity').to_yaml)
|
||||
assert_equal("--- .NaN\n", BigDecimal.new('NaN').to_yaml)
|
||||
assert_equal("--- .Inf\n", BigDecimal.new('Infinity').to_yaml)
|
||||
assert_equal("--- .NaN\n", BigDecimal.new('NaN').to_yaml)
|
||||
assert_equal("--- -.Inf\n", BigDecimal.new('-Infinity').to_yaml)
|
||||
end
|
||||
end
|
||||
|
||||
def test_to_d
|
||||
bd = BigDecimal.new '10'
|
||||
assert_equal bd, bd.to_d
|
||||
end
|
||||
end
|
||||
@@ -4,6 +4,7 @@ require 'bigdecimal'
|
||||
require 'active_support/core_ext/string/access'
|
||||
require 'active_support/ordered_hash'
|
||||
require 'active_support/core_ext/object/conversions'
|
||||
require 'active_support/inflections'
|
||||
|
||||
class HashExtTest < Test::Unit::TestCase
|
||||
class IndifferentHash < HashWithIndifferentAccess
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# encoding: utf-8
|
||||
require 'abstract_unit'
|
||||
require 'active_support/core_ext/string/inflections'
|
||||
require 'active_support/json'
|
||||
|
||||
class TestJSONEncoding < Test::Unit::TestCase
|
||||
|
||||
@@ -35,7 +35,7 @@ cd "#{root_dir}/activesupport" do
|
||||
puts "[CruiseControl] Building Active Support"
|
||||
puts
|
||||
build_results[:activesupport] = rake 'test'
|
||||
# build_results[:activesupport_isolated] = rake 'test:isolated'
|
||||
build_results[:activesupport_isolated] = rake 'test:isolated'
|
||||
end
|
||||
|
||||
system "sudo rm -R #{root_dir}/railties/tmp"
|
||||
@@ -51,7 +51,7 @@ cd "#{root_dir}/actionpack" do
|
||||
puts "[CruiseControl] Building Action Pack"
|
||||
puts
|
||||
build_results[:actionpack] = rake 'test'
|
||||
# build_results[:actionpack_isolated] = rake 'test:isolated'
|
||||
build_results[:actionpack_isolated] = rake 'test:isolated'
|
||||
end
|
||||
|
||||
cd "#{root_dir}/actionmailer" do
|
||||
@@ -59,7 +59,7 @@ cd "#{root_dir}/actionmailer" do
|
||||
puts "[CruiseControl] Building Action Mailer"
|
||||
puts
|
||||
build_results[:actionmailer] = rake 'test'
|
||||
# build_results[:actionmailer_isolated] = rake 'test:isolated'
|
||||
build_results[:actionmailer_isolated] = rake 'test:isolated'
|
||||
end
|
||||
|
||||
cd "#{root_dir}/activemodel" do
|
||||
@@ -67,7 +67,7 @@ cd "#{root_dir}/activemodel" do
|
||||
puts "[CruiseControl] Building Active Model"
|
||||
puts
|
||||
build_results[:activemodel] = rake 'test'
|
||||
# build_results[:activemodel_isolated] = rake 'test:isolated'
|
||||
build_results[:activemodel_isolated] = rake 'test:isolated'
|
||||
end
|
||||
|
||||
rm_f "#{root_dir}/activeresource/debug.log"
|
||||
@@ -76,7 +76,7 @@ cd "#{root_dir}/activeresource" do
|
||||
puts "[CruiseControl] Building Active Resource"
|
||||
puts
|
||||
build_results[:activeresource] = rake 'test'
|
||||
# build_results[:activeresource_isolated] = rake 'test:isolated'
|
||||
build_results[:activeresource_isolated] = rake 'test:isolated'
|
||||
end
|
||||
|
||||
rm_f "#{root_dir}/activerecord/debug.log"
|
||||
@@ -85,7 +85,7 @@ cd "#{root_dir}/activerecord" do
|
||||
puts "[CruiseControl] Building Active Record with MySQL"
|
||||
puts
|
||||
build_results[:activerecord_mysql] = rake 'mysql:rebuild_databases', 'mysql:test'
|
||||
# build_results[:activerecord_mysql_isolated] = rake 'mysql:rebuild_databases', 'mysql:isolated_test'
|
||||
build_results[:activerecord_mysql_isolated] = rake 'mysql:rebuild_databases', 'mysql:isolated_test'
|
||||
end
|
||||
|
||||
cd "#{root_dir}/activerecord" do
|
||||
@@ -93,7 +93,7 @@ cd "#{root_dir}/activerecord" do
|
||||
puts "[CruiseControl] Building Active Record with MySQL2"
|
||||
puts
|
||||
build_results[:activerecord_mysql2] = rake 'mysql:rebuild_databases', 'mysql2:test'
|
||||
# build_results[:activerecord_mysql2_isolated] = rake 'mysql:rebuild_databases', 'mysql2:isolated_test'
|
||||
build_results[:activerecord_mysql2_isolated] = rake 'mysql:rebuild_databases', 'mysql2:isolated_test'
|
||||
end
|
||||
|
||||
cd "#{root_dir}/activerecord" do
|
||||
@@ -101,7 +101,7 @@ cd "#{root_dir}/activerecord" do
|
||||
puts "[CruiseControl] Building Active Record with PostgreSQL"
|
||||
puts
|
||||
build_results[:activerecord_postgresql8] = rake 'postgresql:rebuild_databases', 'postgresql:test'
|
||||
# build_results[:activerecord_postgresql8_isolated] = rake 'postgresql:rebuild_databases', 'postgresql:isolated_test'
|
||||
build_results[:activerecord_postgresql8_isolated] = rake 'postgresql:rebuild_databases', 'postgresql:isolated_test'
|
||||
end
|
||||
|
||||
cd "#{root_dir}/activerecord" do
|
||||
@@ -109,7 +109,7 @@ cd "#{root_dir}/activerecord" do
|
||||
puts "[CruiseControl] Building Active Record with SQLite 3"
|
||||
puts
|
||||
build_results[:activerecord_sqlite3] = rake 'sqlite3:test'
|
||||
# build_results[:activerecord_sqlite3_isolated] = rake 'sqlite3:isolated_test'
|
||||
build_results[:activerecord_sqlite3_isolated] = rake 'sqlite3:isolated_test'
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace :test do
|
||||
Dir["test/#{dir}/*_test.rb"].each do |file|
|
||||
next true if file.include?("fixtures")
|
||||
ruby = File.join(*RbConfig::CONFIG.values_at('bindir', 'RUBY_INSTALL_NAME'))
|
||||
system(ruby, '-Itest', "-I#{File.dirname(__FILE__)}/../activesupport/lib", file)
|
||||
sh(ruby, '-Itest', "-I#{File.dirname(__FILE__)}/../activesupport/lib", file)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -294,7 +294,7 @@ YAML
|
||||
|
||||
boot_rails
|
||||
|
||||
expected = %W(
|
||||
expected_locales = %W(
|
||||
#{RAILS_FRAMEWORK_ROOT}/activesupport/lib/active_support/locale/en.yml
|
||||
#{RAILS_FRAMEWORK_ROOT}/activemodel/lib/active_model/locale/en.yml
|
||||
#{RAILS_FRAMEWORK_ROOT}/activerecord/lib/active_record/locale/en.yml
|
||||
@@ -304,11 +304,11 @@ YAML
|
||||
#{app_path}/app/locales/en.yml
|
||||
).map { |path| File.expand_path(path) }
|
||||
|
||||
actual = I18n.load_path.map { |path| File.expand_path(path) }.find_all do |p|
|
||||
p =~ /^#{RAILS_FRAMEWORK_ROOT}/ || p =~ /^#{@plugin.path}/ || p =~ /^#{app_path}/
|
||||
end
|
||||
actual_locales = I18n.load_path.map { |path|
|
||||
File.expand_path(path)
|
||||
} & expected_locales # remove locales external to Rails
|
||||
|
||||
assert_equal expected, actual
|
||||
assert_equal expected_locales, actual_locales
|
||||
|
||||
assert_equal "2", I18n.t(:foo)
|
||||
assert_equal "1", I18n.t(:bar)
|
||||
|
||||
Reference in New Issue
Block a user