aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG.md7
-rw-r--r--activerecord/lib/active_record/associations/collection_proxy.rb8
-rw-r--r--activerecord/lib/active_record/associations/join_dependency.rb12
-rw-r--r--activerecord/lib/active_record/associations/join_dependency/join_association.rb10
-rw-r--r--activerecord/lib/active_record/migration.rb2
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb8
-rw-r--r--activerecord/lib/active_record/validations/uniqueness.rb2
-rw-r--r--activerecord/test/cases/mixin_test.rb44
-rw-r--r--activerecord/test/cases/relation/delegation_test.rb8
-rw-r--r--activerecord/test/cases/validations/uniqueness_validation_test.rb19
10 files changed, 56 insertions, 64 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 97e5d236a8..43651c9b48 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,5 +1,8 @@
-* Make ActiveRecord::Relation#unscope affect relations it is merged in
- to.
+* Fix validation on uniqueness of empty association.
+
+ *Evgeny Li*
+
+* Make `ActiveRecord::Relation#unscope` affect relations it is merged in to.
*Jon Leighton*
diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb
index 2e70a07962..0b37ecf5b7 100644
--- a/activerecord/lib/active_record/associations/collection_proxy.rb
+++ b/activerecord/lib/active_record/associations/collection_proxy.rb
@@ -787,12 +787,12 @@ module ActiveRecord
# has_many :pets
# end
#
- # person.pets.count #=> 1
- # person.pets.many? #=> false
+ # person.pets.count # => 1
+ # person.pets.many? # => false
#
# person.pets << Pet.new(name: 'Snoopy')
- # person.pets.count #=> 2
- # person.pets.many? #=> true
+ # person.pets.count # => 2
+ # person.pets.many? # => true
#
# You can also pass a block to define criteria. The
# behavior is the same, it returns true if the collection
diff --git a/activerecord/lib/active_record/associations/join_dependency.rb b/activerecord/lib/active_record/associations/join_dependency.rb
index c3ac0680ea..3e743c4bfe 100644
--- a/activerecord/lib/active_record/associations/join_dependency.rb
+++ b/activerecord/lib/active_record/associations/join_dependency.rb
@@ -83,14 +83,14 @@ module ActiveRecord
# end
#
# If I execute `@physician.patients.to_a` then
- # base #=> Physician
- # associations #=> []
- # joins #=> [#<Arel::Nodes::InnerJoin: ...]
+ # base # => Physician
+ # associations # => []
+ # joins # => [#<Arel::Nodes::InnerJoin: ...]
#
# However if I execute `Physician.joins(:appointments).to_a` then
- # base #=> Physician
- # associations #=> [:appointments]
- # joins #=> []
+ # base # => Physician
+ # associations # => [:appointments]
+ # joins # => []
#
def initialize(base, associations, joins)
@alias_tracker = AliasTracker.new(base.connection, joins)
diff --git a/activerecord/lib/active_record/associations/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/join_dependency/join_association.rb
index 191d430636..84e18684d8 100644
--- a/activerecord/lib/active_record/associations/join_dependency/join_association.rb
+++ b/activerecord/lib/active_record/associations/join_dependency/join_association.rb
@@ -86,11 +86,11 @@ module ActiveRecord
# end
#
# If I execute `Physician.joins(:appointments).to_a` then
- # reflection #=> #<ActiveRecord::Reflection::AssociationReflection @macro=:has_many ...>
- # table #=> #<Arel::Table @name="appointments" ...>
- # key #=> physician_id
- # foreign_table #=> #<Arel::Table @name="physicians" ...>
- # foreign_key #=> id
+ # reflection # => #<ActiveRecord::Reflection::AssociationReflection @macro=:has_many ...>
+ # table # => #<Arel::Table @name="appointments" ...>
+ # key # => physician_id
+ # foreign_table # => #<Arel::Table @name="physicians" ...>
+ # foreign_key # => id
#
def build_constraint(klass, table, key, foreign_table, foreign_key)
constraint = table[key].eq(foreign_table[foreign_key])
diff --git a/activerecord/lib/active_record/migration.rb b/activerecord/lib/active_record/migration.rb
index d010f23517..a4247fb6f4 100644
--- a/activerecord/lib/active_record/migration.rb
+++ b/activerecord/lib/active_record/migration.rb
@@ -896,7 +896,7 @@ module ActiveRecord
validate(@migrations)
- ActiveRecord::SchemaMigration.create_table
+ Base.connection.initialize_schema_migrations_table
end
def current_version
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index 473762011b..cacc787eba 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -559,9 +559,9 @@ module ActiveRecord
# Allows you to change a previously set where condition for a given attribute, instead of appending to that condition.
#
- # Post.where(trashed: true).where(trashed: false) #=> WHERE `trashed` = 1 AND `trashed` = 0
- # Post.where(trashed: true).rewhere(trashed: false) #=> WHERE `trashed` = 0
- # Post.where(active: true).where(trashed: true).rewhere(trashed: false) #=> WHERE `active` = 1 AND `trashed` = 0
+ # Post.where(trashed: true).where(trashed: false) # => WHERE `trashed` = 1 AND `trashed` = 0
+ # Post.where(trashed: true).rewhere(trashed: false) # => WHERE `trashed` = 0
+ # Post.where(active: true).where(trashed: true).rewhere(trashed: false) # => WHERE `active` = 1 AND `trashed` = 0
#
# This is short-hand for unscope(where: conditions.keys).where(conditions). Note that unlike reorder, we're only unscoping
# the named conditions -- not the entire where statement.
@@ -708,7 +708,7 @@ module ActiveRecord
# Specifies table from which the records will be fetched. For example:
#
# Topic.select('title').from('posts')
- # #=> SELECT title FROM posts
+ # # => SELECT title FROM posts
#
# Can accept other relation objects. For example:
#
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index b55af692d6..38f37f5c8a 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -48,7 +48,7 @@ module ActiveRecord
def build_relation(klass, table, attribute, value) #:nodoc:
if reflection = klass.reflect_on_association(attribute)
attribute = reflection.foreign_key
- value = value.attributes[reflection.primary_key_column.name]
+ value = value.attributes[reflection.primary_key_column.name] unless value.nil?
end
column = klass.columns_hash[attribute.to_s]
diff --git a/activerecord/test/cases/mixin_test.rb b/activerecord/test/cases/mixin_test.rb
index f927c13979..ad0d5cce27 100644
--- a/activerecord/test/cases/mixin_test.rb
+++ b/activerecord/test/cases/mixin_test.rb
@@ -3,42 +3,11 @@ require "cases/helper"
class Mixin < ActiveRecord::Base
end
-# Let us control what Time.now returns for the TouchTest suite
-class Time
- @@forced_now_time = nil
- cattr_accessor :forced_now_time
-
- class << self
- def now_with_forcing
- if @@forced_now_time
- @@forced_now_time
- else
- now_without_forcing
- end
- end
- alias_method_chain :now, :forcing
- end
-end
-
-
class TouchTest < ActiveRecord::TestCase
fixtures :mixins
def setup
- Time.forced_now_time = Time.now
- end
-
- def teardown
- Time.forced_now_time = nil
- end
-
- def test_time_mocking
- five_minutes_ago = 5.minutes.ago
- Time.forced_now_time = five_minutes_ago
- assert_equal five_minutes_ago, Time.now
-
- Time.forced_now_time = nil
- assert_not_equal five_minutes_ago, Time.now
+ travel_to Time.now
end
def test_update
@@ -68,12 +37,13 @@ class TouchTest < ActiveRecord::TestCase
old_updated_at = stamped.updated_at
- Time.forced_now_time = 5.minutes.from_now
- stamped.lft_will_change!
- stamped.save
+ travel 5.minutes do
+ stamped.lft_will_change!
+ stamped.save
- assert_equal Time.now, stamped.updated_at
- assert_equal old_updated_at, stamped.created_at
+ assert_equal Time.now, stamped.updated_at
+ assert_equal old_updated_at, stamped.created_at
+ end
end
def test_create_turned_off
diff --git a/activerecord/test/cases/relation/delegation_test.rb b/activerecord/test/cases/relation/delegation_test.rb
index 7f99b6841f..13677797cf 100644
--- a/activerecord/test/cases/relation/delegation_test.rb
+++ b/activerecord/test/cases/relation/delegation_test.rb
@@ -32,12 +32,12 @@ module ActiveRecord
end
[:map, :collect].each do |method|
- test "##{method} is delgated" do
+ test "##{method} is delegated" do
assert_responds(target, method)
assert_equal(target.pluck(:body), target.send(method) {|post| post.body })
end
- test "##{method}! is not delgated" do
+ test "##{method}! is not delegated" do
assert_deprecated do
assert_responds(target, "#{method}!")
end
@@ -68,12 +68,12 @@ module ActiveRecord
end
[:map, :collect].each do |method|
- test "##{method} is delgated" do
+ test "##{method} is delegated" do
assert_responds(target, method)
assert_equal(target.pluck(:body), target.send(method) {|post| post.body })
end
- test "##{method}! is not delgated" do
+ test "##{method}! is not delegated" do
assert_deprecated do
assert_responds(target, "#{method}!")
end
diff --git a/activerecord/test/cases/validations/uniqueness_validation_test.rb b/activerecord/test/cases/validations/uniqueness_validation_test.rb
index 56d8db0be9..71cb9d7b1e 100644
--- a/activerecord/test/cases/validations/uniqueness_validation_test.rb
+++ b/activerecord/test/cases/validations/uniqueness_validation_test.rb
@@ -35,6 +35,11 @@ class Employee < ActiveRecord::Base
validates_uniqueness_of :nicknames
end
+class TopicWithUniqEvent < Topic
+ belongs_to :event, foreign_key: :parent_id
+ validates :event, uniqueness: true
+end
+
class UniquenessValidationTest < ActiveRecord::TestCase
fixtures :topics, 'warehouse-things', :developers
@@ -376,4 +381,18 @@ class UniquenessValidationTest < ActiveRecord::TestCase
assert_equal ["has already been taken"], e2.errors[:nicknames], "Should have uniqueness message for nicknames"
end
end
+
+ def test_validate_uniqueness_on_existing_relation
+ event = Event.create
+ assert TopicWithUniqEvent.create(event: event).valid?
+
+ topic = TopicWithUniqEvent.new(event: event)
+ assert_not topic.valid?
+ assert_equal ['has already been taken'], topic.errors[:event]
+ end
+
+ def test_validate_uniqueness_on_empty_relation
+ topic = TopicWithUniqEvent.new
+ assert topic.valid?
+ end
end