Update to Rails 2.3.9 and itextomml 1.3.27
This commit is contained in:
parent
113e0af736
commit
ef30cc22df
200 changed files with 3065 additions and 1204 deletions
5
vendor/rails/activerecord/CHANGELOG
vendored
5
vendor/rails/activerecord/CHANGELOG
vendored
|
@ -1,8 +1,5 @@
|
|||
*2.3.9 (September 4, 2010)*
|
||||
*2.3.8 (May 24, 2010)*
|
||||
|
||||
* Version bump.
|
||||
|
||||
|
||||
*2.3.7 (May 24, 2010)*
|
||||
|
||||
* Version bump.
|
||||
|
|
2
vendor/rails/activerecord/Rakefile
vendored
2
vendor/rails/activerecord/Rakefile
vendored
|
@ -192,7 +192,7 @@ spec = Gem::Specification.new do |s|
|
|||
s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
|
||||
end
|
||||
|
||||
s.add_dependency('activesupport', '= 2.3.8' + PKG_BUILD)
|
||||
s.add_dependency('activesupport', '= 2.3.9' + PKG_BUILD)
|
||||
|
||||
s.files.delete FIXTURES_ROOT + "/fixture_database.sqlite"
|
||||
s.files.delete FIXTURES_ROOT + "/fixture_database_2.sqlite"
|
||||
|
|
|
@ -12,6 +12,8 @@ require 'rbench'
|
|||
|
||||
__DIR__ = File.dirname(__FILE__)
|
||||
$:.unshift "#{__DIR__}/../lib"
|
||||
$:.unshift "#{__DIR__}/../../activesupport/lib"
|
||||
|
||||
require 'active_record'
|
||||
|
||||
conn = { :adapter => 'mysql',
|
||||
|
|
|
@ -282,7 +282,11 @@ module ActiveRecord
|
|||
end
|
||||
through_records.flatten!
|
||||
else
|
||||
records.first.class.preload_associations(records, through_association)
|
||||
options = {}
|
||||
options[:include] = reflection.options[:include] || reflection.options[:source] if reflection.options[:conditions]
|
||||
options[:order] = reflection.options[:order]
|
||||
options[:conditions] = reflection.options[:conditions]
|
||||
records.first.class.preload_associations(records, through_association, options)
|
||||
through_records = records.map {|record| record.send(through_association)}.flatten
|
||||
end
|
||||
through_records.compact!
|
||||
|
@ -357,7 +361,13 @@ module ActiveRecord
|
|||
table_name = reflection.klass.quoted_table_name
|
||||
|
||||
if interface = reflection.options[:as]
|
||||
conditions = "#{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_id"} #{in_or_equals_for_ids(ids)} and #{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_type"} = '#{self.base_class.sti_name}'"
|
||||
parent_type = if reflection.active_record.abstract_class?
|
||||
self.base_class.sti_name
|
||||
else
|
||||
reflection.active_record.sti_name
|
||||
end
|
||||
|
||||
conditions = "#{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_id"} #{in_or_equals_for_ids(ids)} and #{reflection.klass.quoted_table_name}.#{connection.quote_column_name "#{interface}_type"} = '#{parent_type}'"
|
||||
else
|
||||
foreign_key = reflection.primary_key_name
|
||||
conditions = "#{reflection.klass.quoted_table_name}.#{foreign_key} #{in_or_equals_for_ids(ids)}"
|
||||
|
|
|
@ -1782,7 +1782,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def using_limitable_reflections?(reflections)
|
||||
reflections.collect(&:collection?).length.zero?
|
||||
reflections.none?(&:collection?)
|
||||
end
|
||||
|
||||
def column_aliases(join_dependency)
|
||||
|
|
|
@ -234,8 +234,9 @@ module ActiveRecord
|
|||
# See destroy for more info.
|
||||
def destroy_all
|
||||
load_target
|
||||
destroy(@target)
|
||||
reset_target!
|
||||
destroy(@target).tap do
|
||||
reset_target!
|
||||
end
|
||||
end
|
||||
|
||||
def create(attrs = {})
|
||||
|
@ -349,7 +350,17 @@ module ActiveRecord
|
|||
begin
|
||||
if !loaded?
|
||||
if @target.is_a?(Array) && @target.any?
|
||||
@target = find_target + @target.find_all {|t| t.new_record? }
|
||||
@target = find_target.map do |f|
|
||||
i = @target.index(f)
|
||||
if i
|
||||
@target.delete_at(i).tap do |t|
|
||||
keys = ["id"] + t.changes.keys + (f.attribute_names - t.attribute_names)
|
||||
t.attributes = f.attributes.except(*keys)
|
||||
end
|
||||
else
|
||||
f
|
||||
end
|
||||
end + @target
|
||||
else
|
||||
@target = find_target
|
||||
end
|
||||
|
@ -364,6 +375,17 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def method_missing(method, *args)
|
||||
case method.to_s
|
||||
when 'find_or_create'
|
||||
return find(:first, :conditions => args.first) || create(args.first)
|
||||
when /^find_or_create_by_(.*)$/
|
||||
rest = $1
|
||||
return send("find_by_#{rest}", *args) ||
|
||||
method_missing("create_by_#{rest}", *args)
|
||||
when /^create_by_(.*)$/
|
||||
return create($1.split('_and_').zip(args).inject({}) { |h,kv| k,v=kv ; h[k] = v ; h })
|
||||
end
|
||||
|
||||
if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method))
|
||||
if block_given?
|
||||
super { |*block_args| yield(*block_args) }
|
||||
|
@ -411,7 +433,14 @@ module ActiveRecord
|
|||
callback(:before_add, record)
|
||||
yield(record) if block_given?
|
||||
@target ||= [] unless loaded?
|
||||
@target << record unless @reflection.options[:uniq] && @target.include?(record)
|
||||
index = @target.index(record)
|
||||
unless @reflection.options[:uniq] && index
|
||||
if index
|
||||
@target[index] = record
|
||||
else
|
||||
@target << record
|
||||
end
|
||||
end
|
||||
callback(:after_add, record)
|
||||
set_inverse_instance(record, @owner)
|
||||
record
|
||||
|
|
|
@ -230,10 +230,6 @@ module ActiveRecord
|
|||
# It's also possible to instantiate related objects, so a Client class belonging to the clients
|
||||
# table with a +master_id+ foreign key can instantiate master through Client#master.
|
||||
def method_missing(method_id, *args, &block)
|
||||
if method_id == :to_ary || method_id == :to_str
|
||||
raise NoMethodError, "undefined method `#{method_id}' for #{inspect}:#{self.class}"
|
||||
end
|
||||
|
||||
method_name = method_id.to_s
|
||||
|
||||
if self.class.private_method_defined?(method_name)
|
||||
|
|
|
@ -146,12 +146,12 @@ module ActiveRecord
|
|||
# add_autosave_association_callbacks(reflect_on_association(name))
|
||||
# end
|
||||
ASSOCIATION_TYPES.each do |type|
|
||||
module_eval %{
|
||||
module_eval <<-CODE, __FILE__, __LINE__ + 1
|
||||
def #{type}(name, options = {})
|
||||
super
|
||||
add_autosave_association_callbacks(reflect_on_association(name))
|
||||
end
|
||||
}
|
||||
CODE
|
||||
end
|
||||
|
||||
# Adds a validate and save callback for the association as specified by
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require 'yaml'
|
||||
require 'set'
|
||||
require 'active_support/core_ext/class/attribute'
|
||||
|
||||
module ActiveRecord #:nodoc:
|
||||
# Generic Active Record exception class.
|
||||
|
@ -515,7 +516,7 @@ module ActiveRecord #:nodoc:
|
|||
@@timestamped_migrations = true
|
||||
|
||||
# Determine whether to store the full constant name including namespace when using STI
|
||||
superclass_delegating_accessor :store_full_sti_class
|
||||
class_attribute :store_full_sti_class
|
||||
self.store_full_sti_class = false
|
||||
|
||||
# Stores the default scope for the class
|
||||
|
@ -935,11 +936,18 @@ module ActiveRecord #:nodoc:
|
|||
def reset_counters(id, *counters)
|
||||
object = find(id)
|
||||
counters.each do |association|
|
||||
child_class = reflect_on_association(association).klass
|
||||
counter_name = child_class.reflect_on_association(self.name.downcase.to_sym).counter_cache_column
|
||||
child_class = reflect_on_association(association.to_sym).klass
|
||||
belongs_name = self.name.demodulize.underscore.to_sym
|
||||
counter_name = child_class.reflect_on_association(belongs_name).counter_cache_column
|
||||
value = object.send(association).count
|
||||
|
||||
connection.update("UPDATE #{quoted_table_name} SET #{connection.quote_column_name(counter_name)} = #{object.send(association).count} WHERE #{connection.quote_column_name(primary_key)} = #{quote_value(object.id)}", "#{name} UPDATE")
|
||||
connection.update(<<-CMD, "#{name} UPDATE")
|
||||
UPDATE #{quoted_table_name}
|
||||
SET #{connection.quote_column_name(counter_name)} = #{value}
|
||||
WHERE #{connection.quote_column_name(primary_key)} = #{quote_value(object.id)}
|
||||
CMD
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
# A generic "counter updater" implementation, intended primarily to be
|
||||
|
@ -972,19 +980,13 @@ module ActiveRecord #:nodoc:
|
|||
# # SET comment_count = comment_count + 1,
|
||||
# # WHERE id IN (10, 15)
|
||||
def update_counters(id, counters)
|
||||
updates = counters.inject([]) { |list, (counter_name, increment)|
|
||||
sign = increment < 0 ? "-" : "+"
|
||||
list << "#{connection.quote_column_name(counter_name)} = COALESCE(#{connection.quote_column_name(counter_name)}, 0) #{sign} #{increment.abs}"
|
||||
}.join(", ")
|
||||
|
||||
if id.is_a?(Array)
|
||||
ids_list = id.map {|i| quote_value(i)}.join(', ')
|
||||
condition = "IN (#{ids_list})"
|
||||
else
|
||||
condition = "= #{quote_value(id)}"
|
||||
updates = counters.map do |counter_name, value|
|
||||
operator = value < 0 ? '-' : '+'
|
||||
quoted_column = connection.quote_column_name(counter_name)
|
||||
"#{quoted_column} = COALESCE(#{quoted_column}, 0) #{operator} #{value.abs}"
|
||||
end
|
||||
|
||||
update_all(updates, "#{connection.quote_column_name(primary_key)} #{condition}")
|
||||
update_all(updates.join(', '), primary_key => id )
|
||||
end
|
||||
|
||||
# Increment a number field by one, usually representing a count.
|
||||
|
@ -1284,6 +1286,8 @@ module ActiveRecord #:nodoc:
|
|||
|
||||
# Turns the +table_name+ back into a class name following the reverse rules of +table_name+.
|
||||
def class_name(table_name = table_name) # :nodoc:
|
||||
ActiveSupport::Deprecation.warn("ActiveRecord::Base#class_name is deprecated and will be removed in Rails 2.3.9.", caller)
|
||||
|
||||
# remove any prefix and/or suffix from the table name
|
||||
class_name = table_name[table_name_prefix.length..-(table_name_suffix.length + 1)].camelize
|
||||
class_name = class_name.singularize if pluralize_table_names
|
||||
|
@ -2642,7 +2646,7 @@ module ActiveRecord #:nodoc:
|
|||
# Note: The new instance will share a link to the same attributes as the original class. So any change to the attributes in either
|
||||
# instance will affect the other.
|
||||
def becomes(klass)
|
||||
returning klass.new do |became|
|
||||
klass.new.tap do |became|
|
||||
became.instance_variable_set("@attributes", @attributes)
|
||||
became.instance_variable_set("@attributes_cache", @attributes_cache)
|
||||
became.instance_variable_set("@new_record", new_record?)
|
||||
|
@ -2660,12 +2664,20 @@ module ActiveRecord #:nodoc:
|
|||
# Updates all the attributes from the passed-in Hash and saves the record. If the object is invalid, the saving will
|
||||
# fail and false will be returned.
|
||||
def update_attributes(attributes)
|
||||
with_transaction_returning_status(:update_attributes_inside_transaction, attributes)
|
||||
end
|
||||
|
||||
def update_attributes_inside_transaction(attributes) #:nodoc:
|
||||
self.attributes = attributes
|
||||
save
|
||||
end
|
||||
|
||||
# Updates an object just like Base.update_attributes but calls save! instead of save so an exception is raised if the record is invalid.
|
||||
def update_attributes!(attributes)
|
||||
with_transaction_returning_status(:update_attributes_inside_transaction!, attributes)
|
||||
end
|
||||
|
||||
def update_attributes_inside_transaction!(attributes) #:nodoc:
|
||||
self.attributes = attributes
|
||||
save!
|
||||
end
|
||||
|
|
|
@ -10,7 +10,7 @@ module ActiveRecord
|
|||
##
|
||||
# :singleton-method:
|
||||
# The connection handler
|
||||
superclass_delegating_accessor :connection_handler
|
||||
class_attribute :connection_handler
|
||||
self.connection_handler = ConnectionAdapters::ConnectionHandler.new
|
||||
|
||||
# Returns the connection currently associated with the class. This can
|
||||
|
|
|
@ -195,6 +195,7 @@ module ActiveRecord
|
|||
# remove_column(:suppliers, :qualification)
|
||||
# remove_columns(:suppliers, :qualification, :experience)
|
||||
def remove_column(table_name, *column_names)
|
||||
raise ArgumentError.new("You must specify at least one column name. Example: remove_column(:people, :first_name)") if column_names.empty?
|
||||
column_names.flatten.each do |column_name|
|
||||
execute "ALTER TABLE #{quote_table_name(table_name)} DROP #{quote_column_name(column_name)}"
|
||||
end
|
||||
|
|
|
@ -211,6 +211,12 @@ module ActiveRecord
|
|||
log_info(sql, name, 0)
|
||||
nil
|
||||
end
|
||||
rescue SystemExit, SignalException, NoMemoryError => e
|
||||
# Don't re-wrap these exceptions. They are probably not being caused by invalid
|
||||
# sql, but rather some external stimulus beyond the responsibilty of this code.
|
||||
# Additionaly, wrapping these exceptions with StatementInvalid would lead to
|
||||
# meaningful loss of data, such as losing SystemExit#status.
|
||||
raise e
|
||||
rescue Exception => e
|
||||
# Log message and raise exception.
|
||||
# Set last_verification to 0, so that connection gets verified
|
||||
|
|
|
@ -315,6 +315,7 @@ module ActiveRecord
|
|||
rows = []
|
||||
result.each { |row| rows << row }
|
||||
result.free
|
||||
@connection.more_results && @connection.next_result # invoking stored procedures with CLIENT_MULTI_RESULTS requires this to tidy up else connection will be dropped
|
||||
rows
|
||||
end
|
||||
|
||||
|
@ -638,6 +639,7 @@ module ActiveRecord
|
|||
result = execute(sql, name)
|
||||
rows = result.all_hashes
|
||||
result.free
|
||||
@connection.more_results && @connection.next_result # invoking stored procedures with CLIENT_MULTI_RESULTS requires this to tidy up else connection will be dropped
|
||||
rows
|
||||
end
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ module ActiveRecord
|
|||
module ConnectionAdapters #:nodoc:
|
||||
class SQLite3Adapter < SQLiteAdapter # :nodoc:
|
||||
def table_structure(table_name)
|
||||
returning structure = @connection.table_info(quote_table_name(table_name)) do
|
||||
@connection.table_info(quote_table_name(table_name)).tap do |structure|
|
||||
raise(ActiveRecord::StatementInvalid, "Could not find table '#{table_name}'") if structure.empty?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -269,6 +269,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def remove_column(table_name, *column_names) #:nodoc:
|
||||
raise ArgumentError.new("You must specify at least one column name. Example: remove_column(:people, :first_name)") if column_names.empty?
|
||||
column_names.flatten.each do |column_name|
|
||||
alter_table(table_name) do |definition|
|
||||
definition.columns.delete(definition[column_name])
|
||||
|
@ -329,7 +330,7 @@ module ActiveRecord
|
|||
end
|
||||
|
||||
def table_structure(table_name)
|
||||
returning structure = execute("PRAGMA table_info(#{quote_table_name(table_name)})") do
|
||||
execute("PRAGMA table_info(#{quote_table_name(table_name)})").tap do |structure|
|
||||
raise(ActiveRecord::StatementInvalid, "Could not find table '#{table_name}'") if structure.empty?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -44,7 +44,7 @@ module ActiveRecord
|
|||
base.alias_method_chain :update, :dirty
|
||||
base.alias_method_chain :reload, :dirty
|
||||
|
||||
base.superclass_delegating_accessor :partial_updates
|
||||
base.class_attribute :partial_updates
|
||||
base.partial_updates = true
|
||||
|
||||
base.send(:extend, ClassMethods)
|
||||
|
|
|
@ -11,23 +11,23 @@ en:
|
|||
accepted: "must be accepted"
|
||||
empty: "can't be empty"
|
||||
blank: "can't be blank"
|
||||
too_long: "is too long (maximum is {{count}} characters)"
|
||||
too_short: "is too short (minimum is {{count}} characters)"
|
||||
wrong_length: "is the wrong length (should be {{count}} characters)"
|
||||
too_long: "is too long (maximum is %{count} characters)"
|
||||
too_short: "is too short (minimum is %{count} characters)"
|
||||
wrong_length: "is the wrong length (should be %{count} characters)"
|
||||
taken: "has already been taken"
|
||||
not_a_number: "is not a number"
|
||||
greater_than: "must be greater than {{count}}"
|
||||
greater_than_or_equal_to: "must be greater than or equal to {{count}}"
|
||||
equal_to: "must be equal to {{count}}"
|
||||
less_than: "must be less than {{count}}"
|
||||
less_than_or_equal_to: "must be less than or equal to {{count}}"
|
||||
greater_than: "must be greater than %{count}"
|
||||
greater_than_or_equal_to: "must be greater than or equal to %{count}"
|
||||
equal_to: "must be equal to %{count}"
|
||||
less_than: "must be less than %{count}"
|
||||
less_than_or_equal_to: "must be less than or equal to %{count}"
|
||||
odd: "must be odd"
|
||||
even: "must be even"
|
||||
record_invalid: "Validation failed: {{errors}}"
|
||||
record_invalid: "Validation failed: %{errors}"
|
||||
# Append your own errors here or at the model/attributes scope.
|
||||
|
||||
full_messages:
|
||||
format: "{{attribute}} {{message}}"
|
||||
format: "%{attribute} %{message}"
|
||||
|
||||
# You can define own errors for models or model attributes.
|
||||
# The values :model, :attribute and :value are always available for interpolation.
|
||||
|
@ -35,7 +35,7 @@ en:
|
|||
# For example,
|
||||
# models:
|
||||
# user:
|
||||
# blank: "This is a custom blank message for {{model}}: {{attribute}}"
|
||||
# blank: "This is a custom blank message for %{model}: %{attribute}"
|
||||
# attributes:
|
||||
# login:
|
||||
# blank: "This is a custom blank message for User login"
|
||||
|
|
|
@ -128,6 +128,7 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
@destroyed = true
|
||||
freeze
|
||||
end
|
||||
|
||||
|
|
|
@ -516,7 +516,7 @@ module ActiveRecord
|
|||
raise DuplicateMigrationNameError.new(name.camelize)
|
||||
end
|
||||
|
||||
klasses << returning(MigrationProxy.new) do |migration|
|
||||
klasses << (MigrationProxy.new).tap do |migration|
|
||||
migration.name = name.camelize
|
||||
migration.version = version
|
||||
migration.filename = file
|
||||
|
|
|
@ -8,10 +8,7 @@ module ActiveRecord
|
|||
#
|
||||
# You can define a scope that applies to all finders using ActiveRecord::Base.default_scope.
|
||||
def self.included(base)
|
||||
base.class_eval do
|
||||
extend ClassMethods
|
||||
named_scope :scoped, lambda { |scope| scope }
|
||||
end
|
||||
base.extend ClassMethods
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
|
@ -19,6 +16,10 @@ module ActiveRecord
|
|||
read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
|
||||
end
|
||||
|
||||
def scoped(scope, &block)
|
||||
Scope.new(self, scope, &block)
|
||||
end
|
||||
|
||||
# Adds a class method for retrieving and querying objects. A scope represents a narrowing of a database query,
|
||||
# such as <tt>:conditions => {:color => :red}, :select => 'shirts.*', :include => :washing_instructions</tt>.
|
||||
#
|
||||
|
@ -84,18 +85,22 @@ module ActiveRecord
|
|||
# assert_equal expected_options, Shirt.colored('red').proxy_options
|
||||
def named_scope(name, options = {}, &block)
|
||||
name = name.to_sym
|
||||
|
||||
scopes[name] = lambda do |parent_scope, *args|
|
||||
Scope.new(parent_scope, case options
|
||||
when Hash
|
||||
options
|
||||
when Proc
|
||||
options.call(*args)
|
||||
if self.model_name != parent_scope.model_name
|
||||
options.bind(parent_scope).call(*args)
|
||||
else
|
||||
options.call(*args)
|
||||
end
|
||||
end, &block)
|
||||
end
|
||||
(class << self; self end).instance_eval do
|
||||
define_method name do |*args|
|
||||
scopes[name].call(self, *args)
|
||||
end
|
||||
|
||||
singleton_class.send :define_method, name do |*args|
|
||||
scopes[name].call(self, *args)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -286,7 +286,9 @@ module ActiveRecord
|
|||
assign_to_or_mark_for_destruction(record, attributes, options[:allow_destroy])
|
||||
|
||||
elsif attributes['id']
|
||||
raise_nested_attributes_record_not_found(association_name, attributes['id'])
|
||||
existing_record = self.class.reflect_on_association(association_name).klass.find(attributes['id'])
|
||||
assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
|
||||
self.send(association_name.to_s+'=', existing_record)
|
||||
|
||||
elsif !reject_new_record?(association_name, attributes)
|
||||
method = "build_#{association_name}"
|
||||
|
@ -356,11 +358,16 @@ module ActiveRecord
|
|||
unless reject_new_record?(association_name, attributes)
|
||||
association.build(attributes.except(*UNASSIGNABLE_KEYS))
|
||||
end
|
||||
|
||||
elsif existing_records.size == 0 # Existing record but not yet associated
|
||||
existing_record = self.class.reflect_on_association(association_name).klass.find(attributes['id'])
|
||||
association.send(:add_record_to_target_with_callbacks, existing_record) unless association.loaded?
|
||||
assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
|
||||
|
||||
elsif existing_record = existing_records.detect { |record| record.id.to_s == attributes['id'].to_s }
|
||||
association.send(:add_record_to_target_with_callbacks, existing_record) unless association.loaded?
|
||||
assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
|
||||
else
|
||||
raise_nested_attributes_record_not_found(association_name, attributes['id'])
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -380,7 +387,7 @@ module ActiveRecord
|
|||
ConnectionAdapters::Column.value_to_boolean(hash['_destroy'])
|
||||
end
|
||||
|
||||
# Determines if a new record should be build by checking for
|
||||
# Determines if a new record should be built by checking for
|
||||
# has_destroy_flag? or if a <tt>:reject_if</tt> proc exists for this
|
||||
# association and evaluates to +true+.
|
||||
def reject_new_record?(association_name, attributes)
|
||||
|
@ -396,9 +403,5 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
def raise_nested_attributes_record_not_found(association_name, record_id)
|
||||
reflection = self.class.reflect_on_association(association_name)
|
||||
raise RecordNotFound, "Couldn't find #{reflection.klass.name} with ID=#{record_id} for #{self.class.name} with ID=#{id}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -74,7 +74,7 @@ module ActiveRecord #:nodoc:
|
|||
end
|
||||
|
||||
def serializable_record
|
||||
returning(serializable_record = {}) do
|
||||
{}.tap do |serializable_record|
|
||||
serializable_names.each { |name| serializable_record[name] = @record.send(name) }
|
||||
add_includes do |association, records, opts|
|
||||
if records.is_a?(Enumerable)
|
||||
|
|
|
@ -184,7 +184,7 @@ module ActiveRecord
|
|||
|
||||
# Look up a session by id and unmarshal its data if found.
|
||||
def find_by_session_id(session_id)
|
||||
if record = @@connection.select_one("SELECT * FROM #{@@table_name} WHERE #{@@session_id_column}=#{@@connection.quote(session_id)}")
|
||||
if record = connection.select_one("SELECT * FROM #{@@table_name} WHERE #{@@session_id_column}=#{connection.quote(session_id)}")
|
||||
new(:session_id => session_id, :marshaled_data => record['data'])
|
||||
end
|
||||
end
|
||||
|
@ -310,6 +310,14 @@ module ActiveRecord
|
|||
return true
|
||||
end
|
||||
|
||||
def destroy(env)
|
||||
if sid = current_session_id(env)
|
||||
Base.silence do
|
||||
get_session_model(env, sid).destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def get_session_model(env, sid)
|
||||
if env[ENV_SESSION_OPTIONS_KEY][:id].nil?
|
||||
env[SESSION_RECORD_KEY] = find_session(sid)
|
||||
|
|
|
@ -80,7 +80,7 @@ module ActiveRecord
|
|||
|
||||
# Wraps an error message into a full_message format.
|
||||
#
|
||||
# The default full_message format for any locale is <tt>"{{attribute}} {{message}}"</tt>.
|
||||
# The default full_message format for any locale is <tt>"%{attribute} %{message}"</tt>.
|
||||
# One can specify locale specific default full_message format by storing it as a
|
||||
# translation for the key <tt>:"activerecord.errors.full_messages.format"</tt>.
|
||||
#
|
||||
|
@ -109,7 +109,7 @@ module ActiveRecord
|
|||
keys = [
|
||||
:"full_messages.#{@message}",
|
||||
:'full_messages.format',
|
||||
'{{attribute}} {{message}}'
|
||||
'%{attribute} %{message}'
|
||||
]
|
||||
|
||||
options.merge!(:default => keys, :message => self.message)
|
||||
|
@ -604,13 +604,13 @@ module ActiveRecord
|
|||
#
|
||||
# class Person < ActiveRecord::Base
|
||||
# validates_length_of :first_name, :maximum=>30
|
||||
# validates_length_of :last_name, :maximum=>30, :message=>"less than {{count}} if you don't mind"
|
||||
# validates_length_of :last_name, :maximum=>30, :message=>"less than %{count} if you don't mind"
|
||||
# validates_length_of :fax, :in => 7..32, :allow_nil => true
|
||||
# validates_length_of :phone, :in => 7..32, :allow_blank => true
|
||||
# validates_length_of :user_name, :within => 6..20, :too_long => "pick a shorter name", :too_short => "pick a longer name"
|
||||
# validates_length_of :fav_bra_size, :minimum => 1, :too_short => "please enter at least {{count}} character"
|
||||
# validates_length_of :smurf_leader, :is => 4, :message => "papa is spelled with {{count}} characters... don't play me."
|
||||
# validates_length_of :essay, :minimum => 100, :too_short => "Your essay must be at least {{count}} words."), :tokenizer => lambda {|str| str.scan(/\w+/) }
|
||||
# validates_length_of :fav_bra_size, :minimum => 1, :too_short => "please enter at least %{count} character"
|
||||
# validates_length_of :smurf_leader, :is => 4, :message => "papa is spelled with %{count} characters... don't play me."
|
||||
# validates_length_of :essay, :minimum => 100, :too_short => "Your essay must be at least %{count} words."), :tokenizer => lambda {|str| str.scan(/\w+/) }
|
||||
# end
|
||||
#
|
||||
# Configuration options:
|
||||
|
@ -621,9 +621,9 @@ module ActiveRecord
|
|||
# * <tt>:in</tt> - A synonym(or alias) for <tt>:within</tt>.
|
||||
# * <tt>:allow_nil</tt> - Attribute may be +nil+; skip validation.
|
||||
# * <tt>:allow_blank</tt> - Attribute may be blank; skip validation.
|
||||
# * <tt>:too_long</tt> - The error message if the attribute goes over the maximum (default is: "is too long (maximum is {{count}} characters)").
|
||||
# * <tt>:too_short</tt> - The error message if the attribute goes under the minimum (default is: "is too short (min is {{count}} characters)").
|
||||
# * <tt>:wrong_length</tt> - The error message if using the <tt>:is</tt> method and the attribute is the wrong size (default is: "is the wrong length (should be {{count}} characters)").
|
||||
# * <tt>:too_long</tt> - The error message if the attribute goes over the maximum (default is: "is too long (maximum is %{count} characters)").
|
||||
# * <tt>:too_short</tt> - The error message if the attribute goes under the minimum (default is: "is too short (min is %{count} characters)").
|
||||
# * <tt>:wrong_length</tt> - The error message if using the <tt>:is</tt> method and the attribute is the wrong size (default is: "is the wrong length (should be %{count} characters)").
|
||||
# * <tt>:message</tt> - The error message to use for a <tt>:minimum</tt>, <tt>:maximum</tt>, or <tt>:is</tt> violation. An alias of the appropriate <tt>too_long</tt>/<tt>too_short</tt>/<tt>wrong_length</tt> message.
|
||||
# * <tt>:on</tt> - Specifies when this validation is active (default is <tt>:save</tt>, other options <tt>:create</tt>, <tt>:update</tt>).
|
||||
# * <tt>:if</tt> - Specifies a method, proc or string to call to determine if the validation should
|
||||
|
@ -825,7 +825,7 @@ module ActiveRecord
|
|||
if scope = configuration[:scope]
|
||||
Array(scope).map do |scope_item|
|
||||
scope_value = record.send(scope_item)
|
||||
condition_sql << " AND " << attribute_condition("#{record.class.quoted_table_name}.#{scope_item}", scope_value)
|
||||
condition_sql << " AND " << attribute_condition("#{record.class.quoted_table_name}.#{connection.quote_column_name(scope_item)}", scope_value)
|
||||
condition_params << scope_value
|
||||
end
|
||||
end
|
||||
|
@ -885,7 +885,7 @@ module ActiveRecord
|
|||
# class Person < ActiveRecord::Base
|
||||
# validates_inclusion_of :gender, :in => %w( m f )
|
||||
# validates_inclusion_of :age, :in => 0..99
|
||||
# validates_inclusion_of :format, :in => %w( jpg gif png ), :message => "extension {{value}} is not included in the list"
|
||||
# validates_inclusion_of :format, :in => %w( jpg gif png ), :message => "extension %{value} is not included in the list"
|
||||
# end
|
||||
#
|
||||
# Configuration options:
|
||||
|
@ -919,7 +919,7 @@ module ActiveRecord
|
|||
# class Person < ActiveRecord::Base
|
||||
# validates_exclusion_of :username, :in => %w( admin superuser ), :message => "You don't belong here"
|
||||
# validates_exclusion_of :age, :in => 30..60, :message => "This site is only for under 30 and over 60"
|
||||
# validates_exclusion_of :format, :in => %w( mov avi ), :message => "extension {{value}} is not allowed"
|
||||
# validates_exclusion_of :format, :in => %w( mov avi ), :message => "extension %{value} is not allowed"
|
||||
# end
|
||||
#
|
||||
# Configuration options:
|
||||
|
|
|
@ -2,7 +2,7 @@ module ActiveRecord
|
|||
module VERSION #:nodoc:
|
||||
MAJOR = 2
|
||||
MINOR = 3
|
||||
TINY = 8
|
||||
TINY = 9
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY].join('.')
|
||||
end
|
||||
|
|
|
@ -65,15 +65,14 @@ class AdapterTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_not_specifying_database_name_for_cross_database_selects
|
||||
assert_nothing_raised do
|
||||
ActiveRecord::Base.establish_connection({
|
||||
:adapter => 'mysql',
|
||||
:username => 'rails'
|
||||
})
|
||||
ActiveRecord::Base.connection.execute "SELECT activerecord_unittest.pirates.*, activerecord_unittest2.courses.* FROM activerecord_unittest.pirates, activerecord_unittest2.courses"
|
||||
begin
|
||||
assert_nothing_raised do
|
||||
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['arunit'].except(:database))
|
||||
ActiveRecord::Base.connection.execute "SELECT activerecord_unittest.pirates.*, activerecord_unittest2.courses.* FROM activerecord_unittest.pirates, activerecord_unittest2.courses"
|
||||
end
|
||||
ensure
|
||||
ActiveRecord::Base.establish_connection 'arunit'
|
||||
end
|
||||
|
||||
ActiveRecord::Base.establish_connection 'arunit'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ module Remembered
|
|||
|
||||
module ClassMethods
|
||||
def remembered; @@remembered ||= []; end
|
||||
def random_element; @@remembered.random_element; end
|
||||
def sample; @@remembered.sample; end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -82,14 +82,14 @@ class EagerLoadPolyAssocsTest < ActiveRecord::TestCase
|
|||
[Circle, Square, Triangle, NonPolyOne, NonPolyTwo].map(&:create!)
|
||||
end
|
||||
1.upto(NUM_SIMPLE_OBJS) do
|
||||
PaintColor.create!(:non_poly_one_id => NonPolyOne.random_element.id)
|
||||
PaintTexture.create!(:non_poly_two_id => NonPolyTwo.random_element.id)
|
||||
PaintColor.create!(:non_poly_one_id => NonPolyOne.sample.id)
|
||||
PaintTexture.create!(:non_poly_two_id => NonPolyTwo.sample.id)
|
||||
end
|
||||
1.upto(NUM_SHAPE_EXPRESSIONS) do
|
||||
shape_type = [Circle, Square, Triangle].random_element
|
||||
paint_type = [PaintColor, PaintTexture].random_element
|
||||
ShapeExpression.create!(:shape_type => shape_type.to_s, :shape_id => shape_type.random_element.id,
|
||||
:paint_type => paint_type.to_s, :paint_id => paint_type.random_element.id)
|
||||
shape_type = [Circle, Square, Triangle].sample
|
||||
paint_type = [PaintColor, PaintTexture].sample
|
||||
ShapeExpression.create!(:shape_type => shape_type.to_s, :shape_id => shape_type.sample.id,
|
||||
:paint_type => paint_type.to_s, :paint_id => paint_type.sample.id)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
19
vendor/rails/activerecord/test/cases/associations/eager_load_nested_polymorphic_include.rb
vendored
Normal file
19
vendor/rails/activerecord/test/cases/associations/eager_load_nested_polymorphic_include.rb
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
require 'cases/helper'
|
||||
require 'models/tee'
|
||||
require 'models/tie'
|
||||
require 'models/polymorphic_design'
|
||||
require 'models/polymorphic_price'
|
||||
|
||||
class EagerLoadNestedPolymorphicIncludeTest < ActiveRecord::TestCase
|
||||
fixtures :tees, :ties, :polymorphic_designs, :polymorphic_prices
|
||||
|
||||
def test_eager_load_polymorphic_has_one_nested_under_polymorphic_belongs_to
|
||||
designs = PolymorphicDesign.scoped(:include => {:designable => :polymorphic_price})
|
||||
|
||||
associated_price_ids = designs.map{|design| design.designable.polymorphic_price.id}
|
||||
expected_price_ids = [1, 2, 3, 4]
|
||||
|
||||
assert expected_price_ids.all?{|expected_id| associated_price_ids.include?(expected_id)},
|
||||
"Expected associated prices to be #{expected_price_ids.inspect} but they were #{associated_price_ids.sort.inspect}"
|
||||
end
|
||||
end
|
|
@ -357,6 +357,13 @@ class EagerAssociationTest < ActiveRecord::TestCase
|
|||
assert_equal comments(:more_greetings), Author.find(authors(:david).id, :include => :comments_with_order_and_conditions).comments_with_order_and_conditions.first
|
||||
end
|
||||
|
||||
def test_eager_with_has_many_through_with_conditions_join_model_with_include
|
||||
post_tags = Post.find(posts(:welcome).id).misc_tags
|
||||
eager_post_tags = Post.find(1, :include => :misc_tags).misc_tags
|
||||
assert_equal post_tags, eager_post_tags
|
||||
end
|
||||
|
||||
|
||||
def test_eager_with_has_many_through_join_model_with_include
|
||||
author_comments = Author.find(authors(:david).id, :include => :comments_with_include).comments_with_include.to_a
|
||||
assert_no_queries do
|
||||
|
|
|
@ -21,6 +21,68 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|||
Client.destroyed_client_ids.clear
|
||||
end
|
||||
|
||||
def test_create_by
|
||||
person = Person.create! :first_name => 'tenderlove'
|
||||
post = Post.find :first
|
||||
|
||||
assert_equal [], person.readers
|
||||
assert_nil person.readers.find_by_post_id(post.id)
|
||||
|
||||
reader = person.readers.create_by_post_id post.id
|
||||
|
||||
assert_equal 1, person.readers.count
|
||||
assert_equal 1, person.readers.length
|
||||
assert_equal post, person.readers.first.post
|
||||
assert_equal person, person.readers.first.person
|
||||
end
|
||||
|
||||
def test_create_by_multi
|
||||
person = Person.create! :first_name => 'tenderlove'
|
||||
post = Post.find :first
|
||||
|
||||
assert_equal [], person.readers
|
||||
|
||||
reader = person.readers.create_by_post_id_and_skimmer post.id, false
|
||||
|
||||
assert_equal 1, person.readers.count
|
||||
assert_equal 1, person.readers.length
|
||||
assert_equal post, person.readers.first.post
|
||||
assert_equal person, person.readers.first.person
|
||||
end
|
||||
|
||||
def test_find_or_create_by
|
||||
person = Person.create! :first_name => 'tenderlove'
|
||||
post = Post.find :first
|
||||
|
||||
assert_equal [], person.readers
|
||||
assert_nil person.readers.find_by_post_id(post.id)
|
||||
|
||||
reader = person.readers.find_or_create_by_post_id post.id
|
||||
|
||||
assert_equal 1, person.readers.count
|
||||
assert_equal 1, person.readers.length
|
||||
assert_equal post, person.readers.first.post
|
||||
assert_equal person, person.readers.first.person
|
||||
end
|
||||
|
||||
def test_find_or_create
|
||||
person = Person.create! :first_name => 'tenderlove'
|
||||
post = Post.find :first
|
||||
|
||||
assert_equal [], person.readers
|
||||
assert_nil person.readers.find(:first, :conditions => {
|
||||
:post_id => post.id
|
||||
})
|
||||
|
||||
reader = person.readers.find_or_create :post_id => post.id
|
||||
|
||||
assert_equal 1, person.readers.count
|
||||
assert_equal 1, person.readers.length
|
||||
assert_equal post, person.readers.first.post
|
||||
assert_equal person, person.readers.first.person
|
||||
end
|
||||
|
||||
|
||||
def force_signal37_to_load_all_clients_of_firm
|
||||
companies(:first_firm).clients_of_firm.each {|f| }
|
||||
end
|
||||
|
@ -486,7 +548,7 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|||
assert the_client.new_record?
|
||||
end
|
||||
|
||||
def test_find_or_create
|
||||
def test_find_or_create_updates_size
|
||||
number_of_clients = companies(:first_firm).clients.size
|
||||
the_client = companies(:first_firm).clients.find_or_create_by_name("Yet another client")
|
||||
assert_equal number_of_clients + 1, companies(:first_firm, :reload).clients.size
|
||||
|
@ -772,8 +834,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase
|
|||
|
||||
def test_destroy_all
|
||||
force_signal37_to_load_all_clients_of_firm
|
||||
assert !companies(:first_firm).clients_of_firm.empty?, "37signals has clients after load"
|
||||
companies(:first_firm).clients_of_firm.destroy_all
|
||||
clients = companies(:first_firm).clients_of_firm.to_a
|
||||
assert !clients.empty?, "37signals has clients after load"
|
||||
destroyed = companies(:first_firm).clients_of_firm.destroy_all
|
||||
assert_equal clients.sort_by(&:id), destroyed.sort_by(&:id)
|
||||
assert destroyed.all? { |client| client.frozen? }, "destroyed clients should be frozen"
|
||||
assert companies(:first_firm).clients_of_firm.empty?, "37signals has no clients after destroy all"
|
||||
assert companies(:first_firm).clients_of_firm(true).empty?, "37signals has no clients after destroy all and refresh"
|
||||
end
|
||||
|
|
|
@ -18,6 +18,8 @@ require 'models/person'
|
|||
require 'models/reader'
|
||||
require 'models/parrot'
|
||||
require 'models/pirate'
|
||||
require 'models/ship'
|
||||
require 'models/ship_part'
|
||||
require 'models/treasure'
|
||||
require 'models/price_estimate'
|
||||
require 'models/club'
|
||||
|
@ -29,6 +31,23 @@ class AssociationsTest < ActiveRecord::TestCase
|
|||
fixtures :accounts, :companies, :developers, :projects, :developers_projects,
|
||||
:computers, :people, :readers
|
||||
|
||||
def test_loading_the_association_target_should_keep_child_records_marked_for_destruction
|
||||
ship = Ship.create!(:name => "The good ship Dollypop")
|
||||
part = ship.parts.create!(:name => "Mast")
|
||||
part.mark_for_destruction
|
||||
ship.parts.send(:load_target)
|
||||
assert ship.parts[0].marked_for_destruction?
|
||||
end
|
||||
|
||||
def test_loading_the_association_target_should_load_most_recent_attributes_for_child_records_marked_for_destruction
|
||||
ship = Ship.create!(:name => "The good ship Dollypop")
|
||||
part = ship.parts.create!(:name => "Mast")
|
||||
part.mark_for_destruction
|
||||
ShipPart.find(part.id).update_attribute(:name, 'Deck')
|
||||
ship.parts.send(:load_target)
|
||||
assert_equal 'Deck', ship.parts[0].name
|
||||
end
|
||||
|
||||
def test_include_with_order_works
|
||||
assert_nothing_raised {Account.find(:first, :order => 'id', :include => :firm)}
|
||||
assert_nothing_raised {Account.find(:first, :order => :id, :include => :firm)}
|
||||
|
@ -74,6 +93,16 @@ class AssociationsTest < ActiveRecord::TestCase
|
|||
assert_queries(1) { assert_not_nil firm.clients(true).each {} }
|
||||
end
|
||||
end
|
||||
|
||||
def test_using_limitable_reflections_helper
|
||||
using_limitable_reflections = lambda { |reflections| ActiveRecord::Base.send :using_limitable_reflections?, reflections }
|
||||
belongs_to_reflections = [Tagging.reflect_on_association(:tag), Tagging.reflect_on_association(:super_tag)]
|
||||
has_many_reflections = [Tag.reflect_on_association(:taggings), Developer.reflect_on_association(:projects)]
|
||||
mixed_reflections = (belongs_to_reflections + has_many_reflections).uniq
|
||||
assert using_limitable_reflections.call(belongs_to_reflections), "Belong to associations are limitable"
|
||||
assert !using_limitable_reflections.call(has_many_reflections), "All has many style associations are not limitable"
|
||||
assert !using_limitable_reflections.call(mixed_reflections), "No collection associations (has many style) should pass"
|
||||
end
|
||||
|
||||
def test_storing_in_pstore
|
||||
require "tmpdir"
|
||||
|
|
104
vendor/rails/activerecord/test/cases/base_test.rb
vendored
104
vendor/rails/activerecord/test/cases/base_test.rb
vendored
|
@ -1,6 +1,5 @@
|
|||
require "cases/helper"
|
||||
require 'models/post'
|
||||
require 'models/author'
|
||||
require 'models/event_author'
|
||||
require 'models/topic'
|
||||
require 'models/reply'
|
||||
|
@ -588,17 +587,25 @@ class BasicsTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_destroy_all
|
||||
original_count = Topic.count
|
||||
topics_by_mary = Topic.count(:conditions => mary = "author_name = 'Mary'")
|
||||
conditions = "author_name = 'Mary'"
|
||||
topics_by_mary = Topic.all(:conditions => conditions, :order => 'id')
|
||||
assert ! topics_by_mary.empty?
|
||||
|
||||
Topic.destroy_all mary
|
||||
assert_equal original_count - topics_by_mary, Topic.count
|
||||
assert_difference('Topic.count', -topics_by_mary.size) do
|
||||
destroyed = Topic.destroy_all(conditions).sort_by(&:id)
|
||||
assert_equal topics_by_mary, destroyed
|
||||
assert destroyed.all? { |topic| topic.frozen? }
|
||||
end
|
||||
end
|
||||
|
||||
def test_destroy_many
|
||||
assert_equal 3, Client.count
|
||||
Client.destroy([2, 3])
|
||||
assert_equal 1, Client.count
|
||||
clients = Client.find([2, 3], :order => 'id')
|
||||
|
||||
assert_difference('Client.count', -2) do
|
||||
destroyed = Client.destroy([2, 3]).sort_by(&:id)
|
||||
assert_equal clients, destroyed
|
||||
assert destroyed.all? { |client| client.frozen? }
|
||||
end
|
||||
end
|
||||
|
||||
def test_delete_many
|
||||
|
@ -612,55 +619,6 @@ class BasicsTest < ActiveRecord::TestCase
|
|||
assert Topic.find(2).approved?
|
||||
end
|
||||
|
||||
def test_increment_counter
|
||||
Topic.increment_counter("replies_count", 1)
|
||||
assert_equal 2, Topic.find(1).replies_count
|
||||
|
||||
Topic.increment_counter("replies_count", 1)
|
||||
assert_equal 3, Topic.find(1).replies_count
|
||||
end
|
||||
|
||||
def test_decrement_counter
|
||||
Topic.decrement_counter("replies_count", 2)
|
||||
assert_equal -1, Topic.find(2).replies_count
|
||||
|
||||
Topic.decrement_counter("replies_count", 2)
|
||||
assert_equal -2, Topic.find(2).replies_count
|
||||
end
|
||||
|
||||
def test_reset_counters
|
||||
assert_equal 1, Topic.find(1).replies_count
|
||||
|
||||
Topic.increment_counter("replies_count", 1)
|
||||
assert_equal 2, Topic.find(1).replies_count
|
||||
|
||||
Topic.reset_counters(1, :replies)
|
||||
assert_equal 1, Topic.find(1).replies_count
|
||||
end
|
||||
|
||||
def test_update_counter
|
||||
category = categories(:general)
|
||||
assert_nil category.categorizations_count
|
||||
assert_equal 2, category.categorizations.count
|
||||
|
||||
Category.update_counters(category.id, "categorizations_count" => category.categorizations.count)
|
||||
category.reload
|
||||
assert_not_nil category.categorizations_count
|
||||
assert_equal 2, category.categorizations_count
|
||||
|
||||
Category.update_counters(category.id, "categorizations_count" => category.categorizations.count)
|
||||
category.reload
|
||||
assert_not_nil category.categorizations_count
|
||||
assert_equal 4, category.categorizations_count
|
||||
|
||||
category_2 = categories(:technology)
|
||||
count_1, count_2 = (category.categorizations_count || 0), (category_2.categorizations_count || 0)
|
||||
Category.update_counters([category.id, category_2.id], "categorizations_count" => 2)
|
||||
category.reload; category_2.reload
|
||||
assert_equal count_1 + 2, category.categorizations_count
|
||||
assert_equal count_2 + 2, category_2.categorizations_count
|
||||
end
|
||||
|
||||
def test_update_all
|
||||
assert_equal Topic.count, Topic.update_all("content = 'bulk updated!'")
|
||||
assert_equal "bulk updated!", Topic.find(1).content
|
||||
|
@ -749,22 +707,24 @@ class BasicsTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_class_name
|
||||
assert_equal "Firm", ActiveRecord::Base.class_name("firms")
|
||||
assert_equal "Category", ActiveRecord::Base.class_name("categories")
|
||||
assert_equal "AccountHolder", ActiveRecord::Base.class_name("account_holder")
|
||||
ActiveSupport::Deprecation.silence do
|
||||
assert_equal "Firm", ActiveRecord::Base.class_name("firms")
|
||||
assert_equal "Category", ActiveRecord::Base.class_name("categories")
|
||||
assert_equal "AccountHolder", ActiveRecord::Base.class_name("account_holder")
|
||||
|
||||
ActiveRecord::Base.pluralize_table_names = false
|
||||
assert_equal "Firms", ActiveRecord::Base.class_name( "firms" )
|
||||
ActiveRecord::Base.pluralize_table_names = true
|
||||
ActiveRecord::Base.pluralize_table_names = false
|
||||
assert_equal "Firms", ActiveRecord::Base.class_name( "firms" )
|
||||
ActiveRecord::Base.pluralize_table_names = true
|
||||
|
||||
ActiveRecord::Base.table_name_prefix = "test_"
|
||||
assert_equal "Firm", ActiveRecord::Base.class_name( "test_firms" )
|
||||
ActiveRecord::Base.table_name_suffix = "_tests"
|
||||
assert_equal "Firm", ActiveRecord::Base.class_name( "test_firms_tests" )
|
||||
ActiveRecord::Base.table_name_prefix = ""
|
||||
assert_equal "Firm", ActiveRecord::Base.class_name( "firms_tests" )
|
||||
ActiveRecord::Base.table_name_suffix = ""
|
||||
assert_equal "Firm", ActiveRecord::Base.class_name( "firms" )
|
||||
ActiveRecord::Base.table_name_prefix = "test_"
|
||||
assert_equal "Firm", ActiveRecord::Base.class_name( "test_firms" )
|
||||
ActiveRecord::Base.table_name_suffix = "_tests"
|
||||
assert_equal "Firm", ActiveRecord::Base.class_name( "test_firms_tests" )
|
||||
ActiveRecord::Base.table_name_prefix = ""
|
||||
assert_equal "Firm", ActiveRecord::Base.class_name( "firms_tests" )
|
||||
ActiveRecord::Base.table_name_suffix = ""
|
||||
assert_equal "Firm", ActiveRecord::Base.class_name( "firms" )
|
||||
end
|
||||
end
|
||||
|
||||
def test_null_fields
|
||||
|
@ -2090,7 +2050,7 @@ class BasicsTest < ActiveRecord::TestCase
|
|||
|
||||
def test_inspect_instance
|
||||
topic = topics(:first)
|
||||
assert_equal %(#<Topic id: 1, title: "The First Topic", author_name: "David", author_email_address: "david@loudthinking.com", written_on: "#{topic.written_on.to_s(:db)}", bonus_time: "#{topic.bonus_time.to_s(:db)}", last_read: "#{topic.last_read.to_s(:db)}", content: "Have a nice day", approved: false, replies_count: 1, parent_id: nil, parent_title: nil, type: nil>), topic.inspect
|
||||
assert_equal %(#<Topic id: 1, title: "The First Topic", author_name: "David", author_email_address: "david@loudthinking.com", written_on: "#{topic.written_on.to_s(:db)}", bonus_time: "#{topic.bonus_time.to_s(:db)}", last_read: "#{topic.last_read.to_s(:db)}", content: "Have a nice day", approved: false, replies_count: 1, parent_id: nil, parent_title: nil, type: nil, group: nil>), topic.inspect
|
||||
end
|
||||
|
||||
def test_inspect_new_instance
|
||||
|
|
|
@ -48,6 +48,7 @@ class MysqlConnectionTest < ActiveRecord::TestCase
|
|||
def test_multi_results
|
||||
rows = ActiveRecord::Base.connection.select_rows('CALL ten();')
|
||||
assert_equal 10, rows[0][0].to_i, "ten() did not return 10 as expected: #{rows.inspect}"
|
||||
assert @connection.active?, "Bad connection use by 'MysqlAdapter.select_rows'"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
84
vendor/rails/activerecord/test/cases/counter_cache_test.rb
vendored
Executable file
84
vendor/rails/activerecord/test/cases/counter_cache_test.rb
vendored
Executable file
|
@ -0,0 +1,84 @@
|
|||
require 'cases/helper'
|
||||
require 'models/topic'
|
||||
require 'models/reply'
|
||||
require 'models/category'
|
||||
require 'models/categorization'
|
||||
|
||||
class CounterCacheTest < ActiveRecord::TestCase
|
||||
fixtures :topics, :categories, :categorizations
|
||||
|
||||
class SpecialTopic < ::Topic
|
||||
has_many :special_replies, :foreign_key => 'parent_id'
|
||||
end
|
||||
|
||||
class SpecialReply < ::Reply
|
||||
belongs_to :special_topic, :foreign_key => 'parent_id', :counter_cache => 'replies_count'
|
||||
end
|
||||
|
||||
test "increment counter" do
|
||||
topic = Topic.find(1)
|
||||
assert_difference 'topic.reload.replies_count' do
|
||||
Topic.increment_counter(:replies_count, topic.id)
|
||||
end
|
||||
end
|
||||
|
||||
test "decrement counter" do
|
||||
topic = Topic.find(1)
|
||||
assert_difference 'topic.reload.replies_count', -1 do
|
||||
Topic.decrement_counter(:replies_count, topic.id)
|
||||
end
|
||||
end
|
||||
|
||||
test "reset counters" do
|
||||
topic = Topic.find(1)
|
||||
# throw the count off by 1
|
||||
Topic.increment_counter(:replies_count, topic.id)
|
||||
|
||||
# check that it gets reset
|
||||
assert_difference 'topic.reload.replies_count', -1 do
|
||||
Topic.reset_counters(topic.id, :replies)
|
||||
end
|
||||
end
|
||||
|
||||
test "reset counters with string argument" do
|
||||
topic = Topic.find(1)
|
||||
Topic.increment_counter('replies_count', topic.id)
|
||||
|
||||
assert_difference 'topic.reload.replies_count', -1 do
|
||||
Topic.reset_counters(topic.id, 'replies')
|
||||
end
|
||||
end
|
||||
|
||||
test "reset counters with modularized and camelized classnames" do
|
||||
special = SpecialTopic.create!(:title => 'Special')
|
||||
SpecialTopic.increment_counter(:replies_count, special.id)
|
||||
|
||||
assert_difference 'special.reload.replies_count', -1 do
|
||||
SpecialTopic.reset_counters(special.id, :special_replies)
|
||||
end
|
||||
end
|
||||
|
||||
test "update counter with initial null value" do
|
||||
category = categories(:general)
|
||||
assert_equal 2, category.categorizations.count
|
||||
assert_nil category.categorizations_count
|
||||
|
||||
Category.update_counters(category.id, :categorizations_count => category.categorizations.count)
|
||||
assert_equal 2, category.reload.categorizations_count
|
||||
end
|
||||
|
||||
test "update counter for decrement" do
|
||||
topic = Topic.find(1)
|
||||
assert_difference 'topic.reload.replies_count', -3 do
|
||||
Topic.update_counters(topic.id, :replies_count => -3)
|
||||
end
|
||||
end
|
||||
|
||||
test "update counters of multiple records" do
|
||||
t1, t2 = topics(:first, :second)
|
||||
|
||||
assert_difference ['t1.reload.replies_count', 't2.reload.replies_count'], 2 do
|
||||
Topic.update_counters([t1.id, t2.id], :replies_count => 2)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -53,7 +53,8 @@ class OptimisticLockingTest < ActiveRecord::TestCase
|
|||
assert_raises(ActiveRecord::StaleObjectError) { p2.destroy }
|
||||
|
||||
assert p1.destroy
|
||||
assert_equal true, p1.frozen?
|
||||
assert p1.frozen?
|
||||
assert p1.destroyed?
|
||||
assert_raises(ActiveRecord::RecordNotFound) { Person.find(1) }
|
||||
end
|
||||
|
||||
|
|
|
@ -739,6 +739,10 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|||
ActiveRecord::Base.connection.drop_table(:hats)
|
||||
end
|
||||
|
||||
def test_remove_column_no_second_parameter_raises_exception
|
||||
assert_raise(ArgumentError) { Person.connection.remove_column("funny") }
|
||||
end
|
||||
|
||||
def test_change_type_of_not_null_column
|
||||
assert_nothing_raised do
|
||||
Topic.connection.change_column "topics", "written_on", :datetime, :null => false
|
||||
|
|
|
@ -9,6 +9,11 @@ require 'models/developer'
|
|||
class NamedScopeTest < ActiveRecord::TestCase
|
||||
fixtures :posts, :authors, :topics, :comments, :author_addresses
|
||||
|
||||
def test_named_scope_with_STI
|
||||
assert_equal 5,Post.with_type_self.count
|
||||
assert_equal 1,SpecialPost.with_type_self.count
|
||||
end
|
||||
|
||||
def test_implements_enumerable
|
||||
assert !Topic.find(:all).empty?
|
||||
|
||||
|
@ -265,7 +270,7 @@ class NamedScopeTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_rand_should_select_a_random_object_from_proxy
|
||||
assert Topic.approved.random_element.is_a?(Topic)
|
||||
assert Topic.approved.sample.is_a?(Topic)
|
||||
end
|
||||
|
||||
def test_should_use_where_in_query_for_named_scope
|
||||
|
|
|
@ -175,12 +175,6 @@ class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
|
|||
assert_equal 'Davy Jones Gold Dagger', @pirate.ship.name
|
||||
end
|
||||
|
||||
def test_should_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record
|
||||
assert_raise_with_message ActiveRecord::RecordNotFound, "Couldn't find Ship with ID=1234567890 for Pirate with ID=#{@pirate.id}" do
|
||||
@pirate.ship_attributes = { :id => 1234567890 }
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_take_a_hash_with_string_keys_and_update_the_associated_model
|
||||
@pirate.reload.ship_attributes = { 'id' => @ship.id, 'name' => 'Davy Jones Gold Dagger' }
|
||||
|
||||
|
@ -330,10 +324,13 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase
|
|||
assert_equal 'Arr', @ship.pirate.catchphrase
|
||||
end
|
||||
|
||||
def test_should_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record
|
||||
assert_raise_with_message ActiveRecord::RecordNotFound, "Couldn't find Pirate with ID=1234567890 for Ship with ID=#{@ship.id}" do
|
||||
@ship.pirate_attributes = { :id => 1234567890 }
|
||||
end
|
||||
def test_should_associate_with_record_if_parent_record_is_not_saved
|
||||
@ship.destroy
|
||||
@pirate = Pirate.create(:catchphrase => 'Arr')
|
||||
@ship = Ship.new(:name => 'Nights Dirty Lightning', :pirate_attributes => { :id => @pirate.id, :catchphrase => @pirate.catchphrase})
|
||||
|
||||
assert_equal @ship.name, 'Nights Dirty Lightning'
|
||||
assert_equal @pirate, @ship.pirate
|
||||
end
|
||||
|
||||
def test_should_take_a_hash_with_string_keys_and_update_the_associated_model
|
||||
|
@ -437,6 +434,11 @@ module NestedAttributesOnACollectionAssociationTests
|
|||
assert_equal ['Grace OMalley', 'Privateers Greed'], [@child_1.reload.name, @child_2.reload.name]
|
||||
end
|
||||
|
||||
def test_should_assign_existing_children_if_parent_is_new
|
||||
@pirate = Pirate.new({:catchphrase => "Don' botharr talkin' like one, savvy?"}.merge(@alternate_params))
|
||||
assert_equal ['Grace OMalley', 'Privateers Greed'], [@pirate.send(@association_name)[0].name, @pirate.send(@association_name)[1].name]
|
||||
end
|
||||
|
||||
def test_should_take_an_array_and_assign_the_attributes_to_the_associated_models
|
||||
@pirate.send(association_setter, @alternate_params[association_getter].values)
|
||||
@pirate.save
|
||||
|
@ -465,6 +467,33 @@ module NestedAttributesOnACollectionAssociationTests
|
|||
assert_equal 'Grace OMalley', @child_1.reload.name
|
||||
end
|
||||
|
||||
def test_should_not_overwrite_unsaved_updates_when_loading_association
|
||||
@pirate.reload
|
||||
@pirate.send(association_setter, [{ :id => @child_1.id, :name => 'Grace OMalley' }])
|
||||
assert_equal 'Grace OMalley', @pirate.send(@association_name).send(:load_target).find { |r| r.id == @child_1.id }.name
|
||||
end
|
||||
|
||||
def test_should_preserve_order_when_not_overwriting_unsaved_updates
|
||||
@pirate.reload
|
||||
@pirate.send(association_setter, [{ :id => @child_1.id, :name => 'Grace OMalley' }])
|
||||
assert_equal @child_1.id, @pirate.send(@association_name).send(:load_target).first.id
|
||||
end
|
||||
|
||||
def test_should_refresh_saved_records_when_not_overwriting_unsaved_updates
|
||||
@pirate.reload
|
||||
record = @pirate.class.reflect_on_association(@association_name).klass.new(:name => 'Grace OMalley')
|
||||
@pirate.send(@association_name) << record
|
||||
record.save!
|
||||
@pirate.send(@association_name).last.update_attributes!(:name => 'Polly')
|
||||
assert_equal 'Polly', @pirate.send(@association_name).send(:load_target).last.name
|
||||
end
|
||||
|
||||
def test_should_not_remove_scheduled_destroys_when_loading_association
|
||||
@pirate.reload
|
||||
@pirate.send(association_setter, [{ :id => @child_1.id, :_destroy => '1' }])
|
||||
assert @pirate.send(@association_name).send(:load_target).find { |r| r.id == @child_1.id }.marked_for_destruction?
|
||||
end
|
||||
|
||||
def test_should_take_a_hash_with_composite_id_keys_and_assign_the_attributes_to_the_associated_models
|
||||
@child_1.stubs(:id).returns('ABC1X')
|
||||
@child_2.stubs(:id).returns('ABC2X')
|
||||
|
@ -479,8 +508,8 @@ module NestedAttributesOnACollectionAssociationTests
|
|||
assert_equal ['Grace OMalley', 'Privateers Greed'], [@child_1.name, @child_2.name]
|
||||
end
|
||||
|
||||
def test_should_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record
|
||||
assert_raise_with_message ActiveRecord::RecordNotFound, "Couldn't find #{@child_1.class.name} with ID=1234567890 for Pirate with ID=#{@pirate.id}" do
|
||||
def test_should_not_raise_RecordNotFound_if_an_id_is_given_but_doesnt_return_a_record
|
||||
assert_nothing_raised ActiveRecord::RecordNotFound do
|
||||
@pirate.attributes = { association_getter => [{ :id => 1234567890 }] }
|
||||
end
|
||||
end
|
||||
|
@ -781,7 +810,13 @@ class TestHasManyAutosaveAssoictaionWhichItselfHasAutosaveAssociations < ActiveR
|
|||
@part = @ship.parts.create!(:name => "Mast")
|
||||
@trinket = @part.trinkets.create!(:name => "Necklace")
|
||||
end
|
||||
|
||||
|
||||
test "if association is not loaded and association record is saved and then in memory record attributes should be saved" do
|
||||
@ship.parts_attributes=[{:id => @part.id,:name =>'Deck'}]
|
||||
assert_equal 1, @ship.parts.proxy_target.size
|
||||
assert_equal 'Deck', @ship.parts[0].name
|
||||
end
|
||||
|
||||
test "when grandchild changed in memory, saving parent should save grandchild" do
|
||||
@trinket.name = "changed"
|
||||
@ship.save
|
||||
|
@ -810,4 +845,4 @@ class TestHasManyAutosaveAssoictaionWhichItselfHasAutosaveAssociations < ActiveR
|
|||
ShipPart.create!(:ship => @ship, :name => "Stern")
|
||||
assert_no_queries { @ship.valid? }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,25 +24,25 @@ class ReflectionTest < ActiveRecord::TestCase
|
|||
|
||||
def test_read_attribute_names
|
||||
assert_equal(
|
||||
%w( id title author_name author_email_address bonus_time written_on last_read content approved replies_count parent_id parent_title type ).sort,
|
||||
%w( id title author_name author_email_address bonus_time written_on last_read content group approved replies_count parent_id parent_title type ).sort,
|
||||
@first.attribute_names
|
||||
)
|
||||
end
|
||||
|
||||
def test_columns
|
||||
assert_equal 13, Topic.columns.length
|
||||
assert_equal 14, Topic.columns.length
|
||||
end
|
||||
|
||||
def test_columns_are_returned_in_the_order_they_were_declared
|
||||
column_names = Topic.columns.map { |column| column.name }
|
||||
assert_equal %w(id title author_name author_email_address written_on bonus_time last_read content approved replies_count parent_id parent_title type), column_names
|
||||
assert_equal %w(id title author_name author_email_address written_on bonus_time last_read content approved replies_count parent_id parent_title type group), column_names
|
||||
end
|
||||
|
||||
def test_content_columns
|
||||
content_columns = Topic.content_columns
|
||||
content_column_names = content_columns.map {|column| column.name}
|
||||
assert_equal 9, content_columns.length
|
||||
assert_equal %w(title author_name author_email_address written_on bonus_time last_read content approved parent_title).sort, content_column_names.sort
|
||||
assert_equal 10, content_columns.length
|
||||
assert_equal %w(title author_name author_email_address written_on bonus_time last_read content group approved parent_title).sort, content_column_names.sort
|
||||
end
|
||||
|
||||
def test_column_string_type_and_limit
|
||||
|
|
16
vendor/rails/activerecord/test/cases/sp_test_mysql.rb
vendored
Normal file
16
vendor/rails/activerecord/test/cases/sp_test_mysql.rb
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
require "cases/helper"
|
||||
require 'models/topic'
|
||||
require 'models/minimalistic'
|
||||
|
||||
class StoredProcedureTest < ActiveRecord::TestCase
|
||||
fixtures :topics
|
||||
|
||||
# Test that MySQL allows multiple results for stored procedures
|
||||
if Mysql.const_defined?(:CLIENT_MULTI_RESULTS)
|
||||
def test_multi_results_from_find_by_sql
|
||||
topics = Topic.find_by_sql 'CALL topics();'
|
||||
assert_equal 1, topics.size
|
||||
assert ActiveRecord::Base.connection.active?, "Bad connection use by 'MysqlAdapter.select'"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,10 +3,12 @@ require 'models/topic'
|
|||
require 'models/reply'
|
||||
require 'models/developer'
|
||||
require 'models/book'
|
||||
require 'models/author'
|
||||
require 'models/post'
|
||||
|
||||
class TransactionTest < ActiveRecord::TestCase
|
||||
self.use_transactional_fixtures = false
|
||||
fixtures :topics, :developers
|
||||
fixtures :topics, :developers, :authors, :posts
|
||||
|
||||
def setup
|
||||
@first, @second = Topic.find(1, 2).sort_by { |t| t.id }
|
||||
|
@ -34,6 +36,25 @@ class TransactionTest < ActiveRecord::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_update_attributes_should_rollback_on_failure
|
||||
author = Author.find(1)
|
||||
posts_count = author.posts.size
|
||||
assert posts_count > 0
|
||||
status = author.update_attributes(:name => nil, :post_ids => [])
|
||||
assert !status
|
||||
assert_equal posts_count, author.posts(true).size
|
||||
end
|
||||
|
||||
def test_update_attributes_should_rollback_on_failure!
|
||||
author = Author.find(1)
|
||||
posts_count = author.posts.size
|
||||
assert posts_count > 0
|
||||
assert_raise(ActiveRecord::RecordInvalid) do
|
||||
author.update_attributes!(:name => nil, :post_ids => [])
|
||||
end
|
||||
assert_equal posts_count, author.posts(true).size
|
||||
end
|
||||
|
||||
def test_successful_with_return
|
||||
class << Topic.connection
|
||||
alias :real_commit_db_transaction :commit_db_transaction
|
||||
|
|
|
@ -486,20 +486,20 @@ class ActiveRecordErrorI18nTests < ActiveSupport::TestCase
|
|||
end
|
||||
|
||||
test ":default is only given to message if a symbol is supplied" do
|
||||
store_translations(:errors => { :messages => { :"foo bar" => "You fooed: {{value}}." } })
|
||||
store_translations(:errors => { :messages => { :"foo bar" => "You fooed: %{value}." } })
|
||||
@reply.errors.add(:title, :inexistent, :default => "foo bar")
|
||||
assert_equal "foo bar", @reply.errors[:title]
|
||||
end
|
||||
|
||||
test "#generate_message passes the model attribute value for interpolation" do
|
||||
store_translations(:errors => { :messages => { :foo => "You fooed: {{value}}." } })
|
||||
store_translations(:errors => { :messages => { :foo => "You fooed: %{value}." } })
|
||||
@reply.title = "da title"
|
||||
assert_error_message 'You fooed: da title.', :title, :foo
|
||||
end
|
||||
|
||||
test "#generate_message passes the human_name of the model for interpolation" do
|
||||
store_translations(
|
||||
:errors => { :messages => { :foo => "You fooed: {{model}}." } },
|
||||
:errors => { :messages => { :foo => "You fooed: %{model}." } },
|
||||
:models => { :topic => 'da topic' }
|
||||
)
|
||||
assert_error_message 'You fooed: da topic.', :title, :foo
|
||||
|
@ -507,7 +507,7 @@ class ActiveRecordErrorI18nTests < ActiveSupport::TestCase
|
|||
|
||||
test "#generate_message passes the human_name of the attribute for interpolation" do
|
||||
store_translations(
|
||||
:errors => { :messages => { :foo => "You fooed: {{attribute}}." } },
|
||||
:errors => { :messages => { :foo => "You fooed: %{attribute}." } },
|
||||
:attributes => { :topic => { :title => 'da topic title' } }
|
||||
)
|
||||
assert_error_message 'You fooed: da topic title.', :title, :foo
|
||||
|
@ -607,17 +607,17 @@ class ActiveRecordErrorI18nTests < ActiveSupport::TestCase
|
|||
end
|
||||
|
||||
test "#full_message with a format present" do
|
||||
store_translations(:errors => { :messages => { :kaputt => 'is kaputt' }, :full_messages => { :format => '{{attribute}}: {{message}}' } })
|
||||
store_translations(:errors => { :messages => { :kaputt => 'is kaputt' }, :full_messages => { :format => '%{attribute}: %{message}' } })
|
||||
assert_full_message 'Title: is kaputt', :title, :kaputt
|
||||
end
|
||||
|
||||
test "#full_message with a type specific format present" do
|
||||
store_translations(:errors => { :messages => { :kaputt => 'is kaputt' }, :full_messages => { :kaputt => '{{attribute}} {{message}}!' } })
|
||||
store_translations(:errors => { :messages => { :kaputt => 'is kaputt' }, :full_messages => { :kaputt => '%{attribute} %{message}!' } })
|
||||
assert_full_message 'Title is kaputt!', :title, :kaputt
|
||||
end
|
||||
|
||||
test "#full_message with class-level specified custom message" do
|
||||
store_translations(:errors => { :messages => { :broken => 'is kaputt' }, :full_messages => { :broken => '{{attribute}} {{message}}?!' } })
|
||||
store_translations(:errors => { :messages => { :broken => 'is kaputt' }, :full_messages => { :broken => '%{attribute} %{message}?!' } })
|
||||
assert_full_message 'Title is kaputt?!', :title, :kaputt, :message => :broken
|
||||
end
|
||||
|
||||
|
@ -625,7 +625,7 @@ class ActiveRecordErrorI18nTests < ActiveSupport::TestCase
|
|||
store_translations(:my_errors => { :messages => { :kaputt => 'is kaputt' } })
|
||||
assert_full_message 'Title is kaputt', :title, :kaputt, :scope => [:activerecord, :my_errors]
|
||||
|
||||
store_translations(:my_errors => { :full_messages => { :kaputt => '{{attribute}} {{message}}!' } })
|
||||
store_translations(:my_errors => { :full_messages => { :kaputt => '%{attribute} %{message}!' } })
|
||||
assert_full_message 'Title is kaputt!', :title, :kaputt, :scope => [:activerecord, :my_errors]
|
||||
end
|
||||
|
||||
|
@ -763,7 +763,7 @@ class ActiveRecordDefaultErrorMessagesI18nTests < ActiveSupport::TestCase
|
|||
end
|
||||
|
||||
test "custom message string interpolation" do
|
||||
assert_equal 'custom message title', error_message(:invalid, :default => 'custom message {{value}}', :value => 'title')
|
||||
assert_equal 'custom message title', error_message(:invalid, :default => 'custom message %{value}', :value => 'title')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -897,14 +897,14 @@ class ActiveRecordValidationsI18nFullMessagesFullStackTests < ActiveSupport::Tes
|
|||
|
||||
test "full_message format stored per custom error message key" do
|
||||
assert_full_message("Name is broken!") do
|
||||
store_translations :errors => { :messages => { :broken => 'is broken' }, :full_messages => { :broken => '{{attribute}} {{message}}!' } }
|
||||
store_translations :errors => { :messages => { :broken => 'is broken' }, :full_messages => { :broken => '%{attribute} %{message}!' } }
|
||||
I18nPerson.validates_presence_of :name, :message => :broken
|
||||
end
|
||||
end
|
||||
|
||||
test "full_message format stored per error type" do
|
||||
assert_full_message("Name can't be blank!") do
|
||||
store_translations :errors => { :full_messages => { :blank => '{{attribute}} {{message}}!' } }
|
||||
store_translations :errors => { :full_messages => { :blank => '%{attribute} %{message}!' } }
|
||||
I18nPerson.validates_presence_of :name
|
||||
end
|
||||
end
|
||||
|
@ -912,7 +912,7 @@ class ActiveRecordValidationsI18nFullMessagesFullStackTests < ActiveSupport::Tes
|
|||
|
||||
test "full_message format stored as default" do
|
||||
assert_full_message("Name: can't be blank") do
|
||||
store_translations :errors => { :full_messages => { :format => '{{attribute}}: {{message}}' } }
|
||||
store_translations :errors => { :full_messages => { :format => '%{attribute}: %{message}' } }
|
||||
I18nPerson.validates_presence_of :name
|
||||
end
|
||||
end
|
||||
|
|
|
@ -434,6 +434,18 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_validate_uniqueness_with_reserved_word_as_scope
|
||||
repair_validations(Reply) do
|
||||
Topic.validates_uniqueness_of(:content, :scope => "group")
|
||||
|
||||
t1 = Topic.create "title" => "t1", "content" => "hello world2"
|
||||
assert t1.valid?
|
||||
|
||||
t2 = Topic.create "title" => "t2", "content" => "hello world2"
|
||||
assert !t2.valid?
|
||||
end
|
||||
end
|
||||
|
||||
def test_validate_uniqueness_scoped_to_defining_class
|
||||
t = Topic.create("title" => "What, me worry?")
|
||||
|
||||
|
@ -678,7 +690,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_validate_format_with_formatted_message
|
||||
Topic.validates_format_of(:title, :with => /^Valid Title$/, :message => "can't be {{value}}")
|
||||
Topic.validates_format_of(:title, :with => /^Valid Title$/, :message => "can't be %{value}")
|
||||
t = Topic.create(:title => 'Invalid title')
|
||||
assert_equal "can't be Invalid title", t.errors.on(:title)
|
||||
end
|
||||
|
@ -741,7 +753,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_validates_inclusion_of_with_formatted_message
|
||||
Topic.validates_inclusion_of( :title, :in => %w( a b c d e f g ), :message => "option {{value}} is not in the list" )
|
||||
Topic.validates_inclusion_of( :title, :in => %w( a b c d e f g ), :message => "option %{value} is not in the list" )
|
||||
|
||||
assert Topic.create("title" => "a", "content" => "abc").valid?
|
||||
|
||||
|
@ -768,7 +780,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_validates_exclusion_of_with_formatted_message
|
||||
Topic.validates_exclusion_of( :title, :in => %w( abe monkey ), :message => "option {{value}} is restricted" )
|
||||
Topic.validates_exclusion_of( :title, :in => %w( abe monkey ), :message => "option %{value} is restricted" )
|
||||
|
||||
assert Topic.create("title" => "something", "content" => "abc")
|
||||
|
||||
|
@ -868,7 +880,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_optionally_validates_length_of_using_within_on_create
|
||||
Topic.validates_length_of :title, :content, :within => 5..10, :on => :create, :too_long => "my string is too long: {{count}}"
|
||||
Topic.validates_length_of :title, :content, :within => 5..10, :on => :create, :too_long => "my string is too long: %{count}"
|
||||
|
||||
t = Topic.create("title" => "thisisnotvalid", "content" => "whatever")
|
||||
assert !t.save
|
||||
|
@ -889,7 +901,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_optionally_validates_length_of_using_within_on_update
|
||||
Topic.validates_length_of :title, :content, :within => 5..10, :on => :update, :too_short => "my string is too short: {{count}}"
|
||||
Topic.validates_length_of :title, :content, :within => 5..10, :on => :update, :too_short => "my string is too short: %{count}"
|
||||
|
||||
t = Topic.create("title" => "vali", "content" => "whatever")
|
||||
assert !t.save
|
||||
|
@ -953,7 +965,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
def test_validates_length_with_globally_modified_error_message
|
||||
defaults = ActiveSupport::Deprecation.silence { ActiveRecord::Errors.default_error_messages }
|
||||
original_message = defaults[:too_short]
|
||||
defaults[:too_short] = 'tu est trops petit hombre {{count}}'
|
||||
defaults[:too_short] = 'tu est trops petit hombre %{count}'
|
||||
|
||||
Topic.validates_length_of :title, :minimum => 10
|
||||
t = Topic.create(:title => 'too short')
|
||||
|
@ -1004,7 +1016,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_validates_length_of_custom_errors_for_minimum_with_message
|
||||
Topic.validates_length_of( :title, :minimum=>5, :message=>"boo {{count}}" )
|
||||
Topic.validates_length_of( :title, :minimum=>5, :message=>"boo %{count}" )
|
||||
t = Topic.create("title" => "uhoh", "content" => "whatever")
|
||||
assert !t.valid?
|
||||
assert t.errors.on(:title)
|
||||
|
@ -1012,7 +1024,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_validates_length_of_custom_errors_for_minimum_with_too_short
|
||||
Topic.validates_length_of( :title, :minimum=>5, :too_short=>"hoo {{count}}" )
|
||||
Topic.validates_length_of( :title, :minimum=>5, :too_short=>"hoo %{count}" )
|
||||
t = Topic.create("title" => "uhoh", "content" => "whatever")
|
||||
assert !t.valid?
|
||||
assert t.errors.on(:title)
|
||||
|
@ -1020,7 +1032,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_validates_length_of_custom_errors_for_maximum_with_message
|
||||
Topic.validates_length_of( :title, :maximum=>5, :message=>"boo {{count}}" )
|
||||
Topic.validates_length_of( :title, :maximum=>5, :message=>"boo %{count}" )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert !t.valid?
|
||||
assert t.errors.on(:title)
|
||||
|
@ -1028,7 +1040,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_validates_length_of_custom_errors_for_in
|
||||
Topic.validates_length_of(:title, :in => 10..20, :message => "hoo {{count}}")
|
||||
Topic.validates_length_of(:title, :in => 10..20, :message => "hoo %{count}")
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert !t.valid?
|
||||
assert t.errors.on(:title)
|
||||
|
@ -1041,7 +1053,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_validates_length_of_custom_errors_for_maximum_with_too_long
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}" )
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}" )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert !t.valid?
|
||||
assert t.errors.on(:title)
|
||||
|
@ -1049,7 +1061,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_validates_length_of_custom_errors_for_is_with_message
|
||||
Topic.validates_length_of( :title, :is=>5, :message=>"boo {{count}}" )
|
||||
Topic.validates_length_of( :title, :is=>5, :message=>"boo %{count}" )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert !t.valid?
|
||||
assert t.errors.on(:title)
|
||||
|
@ -1057,7 +1069,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_validates_length_of_custom_errors_for_is_with_wrong_length
|
||||
Topic.validates_length_of( :title, :is=>5, :wrong_length=>"hoo {{count}}" )
|
||||
Topic.validates_length_of( :title, :is=>5, :wrong_length=>"hoo %{count}" )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert !t.valid?
|
||||
assert t.errors.on(:title)
|
||||
|
@ -1123,7 +1135,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
|
||||
def test_optionally_validates_length_of_using_within_on_create_utf8
|
||||
with_kcode('UTF8') do
|
||||
Topic.validates_length_of :title, :within => 5..10, :on => :create, :too_long => "長すぎます: {{count}}"
|
||||
Topic.validates_length_of :title, :within => 5..10, :on => :create, :too_long => "長すぎます: %{count}"
|
||||
|
||||
t = Topic.create("title" => "一二三四五六七八九十A", "content" => "whatever")
|
||||
assert !t.save
|
||||
|
@ -1146,7 +1158,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
|
||||
def test_optionally_validates_length_of_using_within_on_update_utf8
|
||||
with_kcode('UTF8') do
|
||||
Topic.validates_length_of :title, :within => 5..10, :on => :update, :too_short => "短すぎます: {{count}}"
|
||||
Topic.validates_length_of :title, :within => 5..10, :on => :update, :too_short => "短すぎます: %{count}"
|
||||
|
||||
t = Topic.create("title" => "一二三4", "content" => "whatever")
|
||||
assert !t.save
|
||||
|
@ -1181,7 +1193,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_validates_length_of_with_block
|
||||
Topic.validates_length_of :content, :minimum => 5, :too_short=>"Your essay must be at least {{count}} words.",
|
||||
Topic.validates_length_of :content, :minimum => 5, :too_short=>"Your essay must be at least %{count} words.",
|
||||
:tokenizer => lambda {|str| str.scan(/\w+/) }
|
||||
t = Topic.create!(:content => "this content should be long enough")
|
||||
assert t.valid?
|
||||
|
@ -1356,7 +1368,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
|
||||
def test_if_validation_using_method_true
|
||||
# When the method returns true
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => :condition_is_true )
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :if => :condition_is_true )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert !t.valid?
|
||||
assert t.errors.on(:title)
|
||||
|
@ -1365,7 +1377,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
|
||||
def test_unless_validation_using_method_true
|
||||
# When the method returns true
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => :condition_is_true )
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :unless => :condition_is_true )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert t.valid?
|
||||
assert !t.errors.on(:title)
|
||||
|
@ -1373,7 +1385,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
|
||||
def test_if_validation_using_method_false
|
||||
# When the method returns false
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => :condition_is_true_but_its_not )
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :if => :condition_is_true_but_its_not )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert t.valid?
|
||||
assert !t.errors.on(:title)
|
||||
|
@ -1381,7 +1393,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
|
||||
def test_unless_validation_using_method_false
|
||||
# When the method returns false
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => :condition_is_true_but_its_not )
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :unless => :condition_is_true_but_its_not )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert !t.valid?
|
||||
assert t.errors.on(:title)
|
||||
|
@ -1390,7 +1402,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
|
||||
def test_if_validation_using_string_true
|
||||
# When the evaluated string returns true
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => "a = 1; a == 1" )
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :if => "a = 1; a == 1" )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert !t.valid?
|
||||
assert t.errors.on(:title)
|
||||
|
@ -1399,7 +1411,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
|
||||
def test_unless_validation_using_string_true
|
||||
# When the evaluated string returns true
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => "a = 1; a == 1" )
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :unless => "a = 1; a == 1" )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert t.valid?
|
||||
assert !t.errors.on(:title)
|
||||
|
@ -1407,7 +1419,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
|
||||
def test_if_validation_using_string_false
|
||||
# When the evaluated string returns false
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :if => "false")
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :if => "false")
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert t.valid?
|
||||
assert !t.errors.on(:title)
|
||||
|
@ -1415,7 +1427,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
|
||||
def test_unless_validation_using_string_false
|
||||
# When the evaluated string returns false
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}", :unless => "false")
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}", :unless => "false")
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert !t.valid?
|
||||
assert t.errors.on(:title)
|
||||
|
@ -1424,7 +1436,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
|
||||
def test_if_validation_using_block_true
|
||||
# When the block returns true
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}",
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}",
|
||||
:if => Proc.new { |r| r.content.size > 4 } )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert !t.valid?
|
||||
|
@ -1434,7 +1446,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
|
||||
def test_unless_validation_using_block_true
|
||||
# When the block returns true
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}",
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}",
|
||||
:unless => Proc.new { |r| r.content.size > 4 } )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert t.valid?
|
||||
|
@ -1443,7 +1455,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
|
||||
def test_if_validation_using_block_false
|
||||
# When the block returns false
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}",
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}",
|
||||
:if => Proc.new { |r| r.title != "uhohuhoh"} )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert t.valid?
|
||||
|
@ -1452,7 +1464,7 @@ class ValidationsTest < ActiveRecord::TestCase
|
|||
|
||||
def test_unless_validation_using_block_false
|
||||
# When the block returns false
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo {{count}}",
|
||||
Topic.validates_length_of( :title, :maximum=>5, :too_long=>"hoo %{count}",
|
||||
:unless => Proc.new { |r| r.title != "uhohuhoh"} )
|
||||
t = Topic.create("title" => "uhohuhoh", "content" => "whatever")
|
||||
assert !t.valid?
|
||||
|
@ -1634,13 +1646,13 @@ class ValidatesNumericalityTest < ActiveRecord::TestCase
|
|||
end
|
||||
|
||||
def test_validates_numericality_with_numeric_message
|
||||
Topic.validates_numericality_of :approved, :less_than => 4, :message => "smaller than {{count}}"
|
||||
Topic.validates_numericality_of :approved, :less_than => 4, :message => "smaller than %{count}"
|
||||
topic = Topic.new("title" => "numeric test", "approved" => 10)
|
||||
|
||||
assert !topic.valid?
|
||||
assert_equal "smaller than 4", topic.errors.on(:approved)
|
||||
|
||||
Topic.validates_numericality_of :approved, :greater_than => 4, :message => "greater than {{count}}"
|
||||
Topic.validates_numericality_of :approved, :greater_than => 4, :message => "greater than %{count}"
|
||||
topic = Topic.new("title" => "numeric test", "approved" => 1)
|
||||
|
||||
assert !topic.valid?
|
||||
|
|
19
vendor/rails/activerecord/test/fixtures/polymorphic_designs.yml
vendored
Normal file
19
vendor/rails/activerecord/test/fixtures/polymorphic_designs.yml
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
awesome_tee_design:
|
||||
id: 1
|
||||
designable_id: 1
|
||||
designable_type: Tee
|
||||
|
||||
sucky_tee_design:
|
||||
id: 2
|
||||
designable_id: 2
|
||||
designable_type: Tee
|
||||
|
||||
awesome_hat_design:
|
||||
id: 3
|
||||
designable_id: 1
|
||||
designable_type: Tie
|
||||
|
||||
sucky_hat_design:
|
||||
id: 4
|
||||
designable_id: 2
|
||||
designable_type: Tie
|
19
vendor/rails/activerecord/test/fixtures/polymorphic_prices.yml
vendored
Normal file
19
vendor/rails/activerecord/test/fixtures/polymorphic_prices.yml
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
awesome_tee_price:
|
||||
id: 1
|
||||
sellable_id: 1
|
||||
sellable_type: Tee
|
||||
|
||||
sucky_tee_price:
|
||||
id: 2
|
||||
sellable_id: 2
|
||||
sellable_type: Tee
|
||||
|
||||
awesome_hat_price:
|
||||
id: 3
|
||||
sellable_id: 1
|
||||
sellable_type: Tie
|
||||
|
||||
sucky_hat_price:
|
||||
id: 4
|
||||
sellable_id: 2
|
||||
sellable_type: Tie
|
4
vendor/rails/activerecord/test/fixtures/tees.yml
vendored
Normal file
4
vendor/rails/activerecord/test/fixtures/tees.yml
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
awesome_tee:
|
||||
id: 1
|
||||
sucky_tee:
|
||||
id: 2
|
4
vendor/rails/activerecord/test/fixtures/ties.yml
vendored
Normal file
4
vendor/rails/activerecord/test/fixtures/ties.yml
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
awesome_tie:
|
||||
id: 1
|
||||
sucky_tie:
|
||||
id: 2
|
|
@ -106,6 +106,8 @@ class Author < ActiveRecord::Base
|
|||
"#{id}-#{name}"
|
||||
end
|
||||
|
||||
validates_presence_of :name
|
||||
|
||||
private
|
||||
def log_before_adding(object)
|
||||
@post_log << "before_adding#{object.id || '<new>'}"
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
require 'models/author'
|
||||
require 'models/event'
|
||||
|
||||
class EventAuthor < ActiveRecord::Base
|
||||
belongs_to :author
|
||||
belongs_to :event
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class Pirate < ActiveRecord::Base
|
||||
belongs_to :parrot, :validate => true
|
||||
belongs_to :non_validated_parrot, :class_name => 'Parrot'
|
||||
has_and_belongs_to_many :parrots, :validate => true
|
||||
has_and_belongs_to_many :parrots, :validate => true, :order => 'parrots.id ASC'
|
||||
has_and_belongs_to_many :non_validated_parrots, :class_name => 'Parrot'
|
||||
has_and_belongs_to_many :parrots_with_method_callbacks, :class_name => "Parrot",
|
||||
:before_add => :log_before_add,
|
||||
|
@ -21,7 +21,7 @@ class Pirate < ActiveRecord::Base
|
|||
has_one :ship
|
||||
has_one :update_only_ship, :class_name => 'Ship'
|
||||
has_one :non_validated_ship, :class_name => 'Ship'
|
||||
has_many :birds
|
||||
has_many :birds, :order => 'birds.id ASC'
|
||||
has_many :birds_with_method_callbacks, :class_name => "Bird",
|
||||
:before_add => :log_before_add,
|
||||
:after_add => :log_after_add,
|
||||
|
|
3
vendor/rails/activerecord/test/models/polymorphic_design.rb
vendored
Normal file
3
vendor/rails/activerecord/test/models/polymorphic_design.rb
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
class PolymorphicDesign < ActiveRecord::Base
|
||||
belongs_to :designable, :polymorphic => true
|
||||
end
|
3
vendor/rails/activerecord/test/models/polymorphic_price.rb
vendored
Normal file
3
vendor/rails/activerecord/test/models/polymorphic_price.rb
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
class PolymorphicPrice < ActiveRecord::Base
|
||||
belongs_to :sellable, :polymorphic => true
|
||||
end
|
|
@ -1,4 +1,5 @@
|
|||
class Post < ActiveRecord::Base
|
||||
named_scope :with_type_self, lambda{{:conditions => ["type=?", self.name]}}
|
||||
named_scope :containing_the_letter_a, :conditions => "body LIKE '%a%'"
|
||||
named_scope :ranked_by_comments, :order => "comments_count DESC"
|
||||
named_scope :limit, lambda {|limit| {:limit => limit} }
|
||||
|
@ -52,6 +53,7 @@ class Post < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
has_many :misc_tags, :through => :taggings, :source => :tag, :conditions => "tags.name = 'Misc'"
|
||||
has_many :funky_tags, :through => :taggings, :source => :tag
|
||||
has_many :super_tags, :through => :taggings
|
||||
has_one :tagging, :as => :taggable
|
||||
|
|
4
vendor/rails/activerecord/test/models/tee.rb
vendored
Normal file
4
vendor/rails/activerecord/test/models/tee.rb
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
class Tee < ActiveRecord::Base
|
||||
has_one :polymorphic_design, :as => :designable
|
||||
has_one :polymorphic_price, :as => :sellable
|
||||
end
|
4
vendor/rails/activerecord/test/models/tie.rb
vendored
Normal file
4
vendor/rails/activerecord/test/models/tie.rb
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
class Tie < ActiveRecord::Base
|
||||
has_one :polymorphic_design, :as => :designable
|
||||
has_one :polymorphic_price, :as => :sellable
|
||||
end
|
|
@ -19,6 +19,13 @@ CREATE PROCEDURE ten() SQL SECURITY INVOKER
|
|||
BEGIN
|
||||
select 10;
|
||||
END
|
||||
SQL
|
||||
|
||||
ActiveRecord::Base.connection.execute <<-SQL
|
||||
CREATE PROCEDURE topics() SQL SECURITY INVOKER
|
||||
BEGIN
|
||||
select * from topics limit 1;
|
||||
END
|
||||
SQL
|
||||
|
||||
end
|
||||
|
|
16
vendor/rails/activerecord/test/schema/schema.rb
vendored
16
vendor/rails/activerecord/test/schema/schema.rb
vendored
|
@ -367,6 +367,16 @@ ActiveRecord::Schema.define do
|
|||
t.column :updated_on, :datetime
|
||||
end
|
||||
|
||||
create_table :polymorphic_designs, :force => true do |t|
|
||||
t.integer :designable_id
|
||||
t.string :designable_type
|
||||
end
|
||||
|
||||
create_table :polymorphic_prices, :force => true do |t|
|
||||
t.integer :sellable_id
|
||||
t.string :sellable_type
|
||||
end
|
||||
|
||||
create_table :posts, :force => true do |t|
|
||||
t.integer :author_id
|
||||
t.string :title, :null => false
|
||||
|
@ -390,6 +400,7 @@ ActiveRecord::Schema.define do
|
|||
create_table :readers, :force => true do |t|
|
||||
t.integer :post_id, :null => false
|
||||
t.integer :person_id, :null => false
|
||||
t.boolean :skimmer, :default => false
|
||||
end
|
||||
|
||||
create_table :shape_expressions, :force => true do |t|
|
||||
|
@ -435,6 +446,8 @@ ActiveRecord::Schema.define do
|
|||
t.datetime :ending
|
||||
end
|
||||
|
||||
create_table :ties, :force => true
|
||||
|
||||
create_table :topics, :force => true do |t|
|
||||
t.string :title
|
||||
t.string :author_name
|
||||
|
@ -448,6 +461,7 @@ ActiveRecord::Schema.define do
|
|||
t.integer :parent_id
|
||||
t.string :parent_title
|
||||
t.string :type
|
||||
t.string :group
|
||||
end
|
||||
|
||||
create_table :taggings, :force => true do |t|
|
||||
|
@ -462,6 +476,8 @@ ActiveRecord::Schema.define do
|
|||
t.column :taggings_count, :integer, :default => 0
|
||||
end
|
||||
|
||||
create_table :tees, :force => true
|
||||
|
||||
create_table :toys, :primary_key => :toy_id ,:force => true do |t|
|
||||
t.string :name
|
||||
t.integer :pet_id, :integer
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue