mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Support passing record to uniqueness conditions
This commit is contained in:
parent
ae5ecfe26c
commit
ab20be81e3
3 changed files with 51 additions and 1 deletions
|
@ -1,3 +1,16 @@
|
|||
* Support passing record to uniqueness validator `:conditions` callable:
|
||||
|
||||
```ruby
|
||||
class Article < ApplicationRecord
|
||||
validates_uniqueness_of :title, conditions: ->(article) {
|
||||
published_at = article.published_at
|
||||
where(published_at: published_at.beginning_of_year..published_at.end_of_year)
|
||||
}
|
||||
end
|
||||
```
|
||||
|
||||
*Eliot Sykes*
|
||||
|
||||
* `BatchEnumerator#update_all` and `BatchEnumerator#delete_all` now return the
|
||||
total number of rows affected, just like their non-batched counterparts.
|
||||
|
||||
|
|
|
@ -29,7 +29,16 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
relation = scope_relation(record, relation)
|
||||
relation = relation.merge(options[:conditions]) if options[:conditions]
|
||||
|
||||
if options[:conditions]
|
||||
conditions = options[:conditions]
|
||||
|
||||
relation = if conditions.arity.zero?
|
||||
relation.instance_exec(&conditions)
|
||||
else
|
||||
relation.instance_exec(record, &conditions)
|
||||
end
|
||||
end
|
||||
|
||||
if relation.exists?
|
||||
error_options = options.except(:case_sensitive, :scope, :conditions)
|
||||
|
@ -126,6 +135,17 @@ module ActiveRecord
|
|||
# validates_uniqueness_of :title, conditions: -> { where.not(status: 'archived') }
|
||||
# end
|
||||
#
|
||||
# To build conditions based on the record's state, define the conditions
|
||||
# callable with a parameter, which will be the record itself. This
|
||||
# example validates the title is unique for the year of publication:
|
||||
#
|
||||
# class Article < ActiveRecord::Base
|
||||
# validates_uniqueness_of :title, conditions: ->(article) {
|
||||
# published_at = article.published_at
|
||||
# where(published_at: published_at.beginning_of_year..published_at.end_of_year)
|
||||
# }
|
||||
# end
|
||||
#
|
||||
# When the record is created, a check is performed to make sure that no
|
||||
# record exists in the database with the given value for the specified
|
||||
# attribute (that maps to a column). When the record is updated,
|
||||
|
|
|
@ -522,6 +522,23 @@ class UniquenessValidationTest < ActiveRecord::TestCase
|
|||
}
|
||||
end
|
||||
|
||||
def test_validate_uniqueness_with_conditions_with_record_arg
|
||||
Topic.validates_uniqueness_of :title, conditions: ->(record) {
|
||||
where(written_on: record.written_on.beginning_of_day..record.written_on.end_of_day)
|
||||
}
|
||||
|
||||
today_midday = Time.current.midday
|
||||
|
||||
todays_topic = Topic.new(title: "Highlights of the Day", written_on: today_midday)
|
||||
assert todays_topic.save, "1st topic written today with this title should save"
|
||||
|
||||
todays_topic_duplicate = Topic.new(title: "Highlights of the Day", written_on: today_midday + 1.minute)
|
||||
assert todays_topic_duplicate.invalid?, "2nd topic written today with this title should be invalid"
|
||||
|
||||
tomorrows_topic = Topic.new(title: "Highlights of the Day", written_on: today_midday + 1.day)
|
||||
assert tomorrows_topic.valid?, "1st topic written tomorrow with this title should be valid"
|
||||
end
|
||||
|
||||
def test_validate_uniqueness_on_existing_relation
|
||||
event = Event.create
|
||||
assert_predicate TopicWithUniqEvent.create(event: event), :valid?
|
||||
|
|
Loading…
Reference in a new issue