aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/validations
Commit message (Collapse)AuthorAgeFilesLines
* Deprecate the behavior of AR::Dirty inside of after_(create|update|save) ↵Sean Griffin2016-11-011-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | callbacks We pretty frequently get bug reports that "dirty is broken inside of after callbacks". Intuitively they are correct. You'd expect `Model.after_save { puts changed? }; model.save` to do the same thing as `model.save; puts model.changed?`, but it does not. However, changing this goes much farther than just making the behavior more intuitive. There are a _ton_ of places inside of AR that can be drastically simplified with this change. Specifically, autosave associations, timestamps, touch, counter cache, and just about anything else in AR that works with callbacks have code to try to avoid "double save" bugs which we will be able to flat out remove with this change. We introduce two new sets of methods, both with names that are meant to be more explicit than dirty. The first set maintains the old behavior, and their names are meant to center that they are about changes that occurred during the save that just happened. They are equivalent to `previous_changes` when called outside of after callbacks, or once the deprecation cycle moves. The second set is the new behavior. Their names imply that they are talking about changes from the database representation. The fact that this is what we really care about became clear when looking at `BelongsTo.touch_record` when tests were failing. I'm unsure that this set of methods should be in the public API. Outside of after callbacks, they are equivalent to the existing methods on dirty. Dirty itself is not deprecated, nor are the methods inside of it. They will only emit the warning when called inside of after callbacks. The scope of this breakage is pretty large, but the migration path is simple. Given how much this can improve our codebase, and considering that it makes our API more intuitive, I think it's worth doing.
* Revert "Extract `PredicateBuilder::CaseSensitiveHandler`"Sean Griffin2016-08-311-1/+31
| | | | | | | | | This reverts commit 3a1f6fe7b4a70bf0698b0684dd48ac712c6883b6. This commit takes the code in a direction that I am looking to avoid. The predicate builder should be purely concerned with AST construction as it matters to methods like `where`. Things like case sensitivity should continue to be handled elsewhere.
* Extract `PredicateBuilder::CaseSensitiveHandler`Ryuta Kamizono2016-08-161-31/+1
| | | | | | Currently uniqueness validator is coupled with building Arel ASTs. This commit extracts `PredicateBuilder::CaseSensitiveHandler` for decouple the building Arel ASTs.
* Revert passing arel node with splat binds for `where`Ryuta Kamizono2016-08-061-2/+5
| | | | | | | | | | | | Passing arel node with splat binds for `where` was introduced at #22877 for uniqueness validator supports prepared statement. But I'd not like to introduce the following usage: ```ruby Foo.where(arel, *binds) ``` I'd like to revert this internal usage.
* Don't passing a nil value to `case_sensitive_comparison`Ryuta Kamizono2016-08-061-7/+7
| | | | | A `value` is only used for checking `value.nil?`. It is unnecessary if immediately return when `value.nil?`.
* Remove unused `table` arg for `UniquenessValidator#scope_relation`Ryuta Kamizono2016-07-181-5/+5
|
* Prevent `RangeError` for `FinderMethods#exists?`Ryuta Kamizono2016-06-161-1/+0
| | | | | | | | | | | | | `FinderMethods#exists?` should return a boolean rather than raising an exception. `UniquenessValidator#build_relation` catches a `RangeError` because it includes type casting due to a string value truncation. But a string value truncation was removed at #23523 then type casting in `build_relation` is no longer necessary. aa06231 removes type casting in `build_relation` then a `RangeError` moves to `relation.exists?`. This change will remove the catching a `RangeError`.
* Avoid type casting in uniqueness validatorRyuta Kamizono2016-06-041-5/+2
| | | | | Type casting in uniqueness validator is for a string value truncation. It was removed at #23523.
* Merge pull request #23523 from kamipo/avoid_truncation_in_uniqueness_validationJeremy Daer2016-04-181-3/+0
|\ | | | | | | Avoid a string value truncation in uniqueness validation
| * Avoid a string value truncation in uniqueness validationRyuta Kamizono2016-02-121-3/+0
| | | | | | | | | | | | | | | | | | In MySQL, PostgreSQL, Oracle and SQLServer, a value over the limit cannot be inserted or updated (See #23522). In SQLite3, a value is inserted or updated regardless of the limit. We should avoid a string value truncation in uniqueness validation.
* | Fix uniqueness validation with an after_create hook.Joe Rafaniello2016-02-251-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | record.id_was is nil in after_create/after_save, so we should use id in these cases. While this logic feels incomplete, the existing update_record uses the same logic: https://github.com/rails/rails/blob/2fda4e0874a97a76107ab9e88305169f2c625933/activerecord/lib/active_record/relation.rb#L83 This logic was originally added for a similar problem: updates not working with after_create hook. See: 482f8c15b1d699c95bfbc3d836f674a09c0d9031 Followup to #23581 Fixes #23844
* | Revert changes to validations from PR #18612eileencodes2016-02-234-15/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In order to fix issue #17621 we added a check to validations that determined if a record should be validated. Based on the existing tests and behavior we wanted we determined the best way to do that was by checking if `!record.peristed? || record.changed? || record.marked_for_destruction?` This change didn't make it into a release until now. When #23790 was opened we realized that `valid?` and `invalid?` were broken and did not work on persisted records because of the `!record.persisted?`. While there is still a bug that #17621 brought up, this change was too drastic and should not be a RC blocker. I will work on fixing this so that we don't break `valid?` but also aren't validating parent records through child records if that parent record is validate false. This change removes the code changes to validate and the corresponding tests. It adds tests for two of the bugs found since Rails 5 beta2 release. Fixes #17621
* | Merge pull request #23628 from maclover7/fix-23625Sean Griffin2016-02-231-1/+1
|\ \ | | | | | | Fix issue #23625
| * | Fix issue #23625Jon Moss2016-02-181-1/+1
| |/ | | | | | | | | | | This resolves a bug where if the primary key used is not `id` (ex: `uuid`), and has a `validates_uniqueness_of` in the model, a uniqueness error would be raised. This is a partial revert of commit `119b9181ece399c67213543fb5227b82688b536f`, which introduced this behavior.
* | Reduce `attribute.to_s`Ryuta Kamizono2016-02-221-6/+5
| |
* | Always validate record if validating a virtual attributeeileencodes2016-02-203-3/+3
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fixes #23645 When you're using an `attr_accessor` for a record instead of an attribute in the database there's no way for the record to know if it has `changed?` unless you tell it `attribute_will_change!("attribute")`. The change made in 27aa4dd updated validations to check if a record was `changed?` or `marked_for_destruction?` or not `persisted?`. It did not take into account virtual attributes that do not affect the model's dirty status. The only way to fix this is to always validate the record if the attribute does not belong to the set of attributes the record expects (in `record.attributes`) because virtual attributes will not be in that hash. I think we should consider deprecating this particular behavior in the future and requiring that the user mark the record dirty by noting that the virtual attribute will change. Unfortunately this isn't easy because we have no way of knowing that you did the "right thing" in your application by marking it dirty and will get the deprecation warning even if you are doing the correct thing. For now this restores expected behavior when using a virtual attribute by always validating the record, as well as adds tests for this case. I was going to add the `!record.attributes.include?(attribute)` to the `should_validate?` method but `uniqueness` cannot validate a virtual attribute with nothing to hold on to the attribute. Because of this `should_validate?` was about to become a very messy method so I decided to split them up so we can handle it specifically for each case.
* UniquenessValidator exclude itself when PK changedDiego Silva2016-02-091-1/+1
| | | | | | | When changing the PK for a record which has a uniqueness validation on some other attribute, Active Record should exclude itself from the validation based on the PK value stored on the DB (id_was) instead of its new value (id).
* Refactor `case_{sensitive|insensitive}_comparison`Ryuta Kamizono2016-01-011-3/+6
| | | | | | | | | | | | | | Before: ``` SELECT 1 AS one FROM "topics" WHERE "topics"."title" = 'abc' LIMIT $1 [["LIMIT", 1]] ``` After: ``` SELECT 1 AS one FROM "topics" WHERE "topics"."title" = $1 LIMIT $2 [["title", "abc"], ["LIMIT", 1]] ```
* Remove legacy mysql adapterAbdelkader Boudih2015-12-171-1/+0
|
* Improve support for non Active Record objects on `validates_associated`Kassio Borges2015-11-081-2/+8
| | | | | | Skipping `marked_for_destruction?` when the associated object does not responds to it make easier to validate virtual associations built on top of Active Model objects and/or serialized objects that implement a `valid?` instance method.
* applies new doc guidelines to Active Record.Yves Senn2015-10-143-8/+11
| | | | | | | | | | | | | | | | | | | The focus of this change is to make the API more accessible. References to method and classes should be linked to make it easy to navigate around. This patch makes exzessiv use of `rdoc-ref:` to provide more readable docs. This makes it possible to document `ActiveRecord::Base#save` even though the method is within a separate module `ActiveRecord::Persistence`. The goal here is to bring the API closer to the actual code that you would write. This commit only deals with Active Record. The other gems will be updated accordingly but in different commits. The pass through Active Record is not completely finished yet. A follow up commit will change the spots I haven't yet had the time to update. /cc @fxn
* uniqueness validation raises error for persisted record without pk.Yves Senn2015-08-201-1/+5
| | | | | | | | Closes #21304. While we can validate uniqueness for record without primary key on creation, there is no way to exclude the current record when updating. (The update itself will need a primary key to work correctly).
* Properly allow uniqueness validations on primary keys.Sean Griffin2015-07-251-1/+3
| | | | | | This is an alternate implementation of #20966. [Sean Griffin & presskey]
* A few documentation fixes [ci skip]Robin Dupret2015-06-231-1/+1
|
* refactor, don't duplicate presence validator logic.Yves Senn2015-06-221-10/+4
| | | | | This is a small refactoring that simplifies the Active Record specific lenght validator.
* docs, update Active Model reference for AR length validator. [ci skip]Yves Senn2015-06-221-1/+4
|
* AR absence validator respects `marked_for_destruction?`. Closes #20449.Yves Senn2015-06-221-0/+24
| | | | Associated objects that were marked for destruction are considered absent.
* Missing note on validates_presence_of validation [ci skip]Mehmet Emin İNAÇ2015-04-111-0/+4
| | | | | | Without this note, someone can misunderstand the usage of validates_presence_of method add missing note for the validates_presence_of
* Fix uniqueness validation with out of range valueAndrey Voronkov2015-04-081-0/+2
|
* `type_cast_for_database` -> `serialize`Sean Griffin2015-02-171-1/+1
|
* rm `Type#text?`Sean Griffin2015-02-071-1/+1
| | | | | | | | | | | | | | | | This predicate was only to figure out if it's safe to do case insensitive comparison, which is only a problem on PG. Turns out, PG can just tell us whether we are able to do it or not. If the query turns out to be a problem, let's just replace that method with checking the SQL type for `text` or `character`. I'd rather not burden the type objects with adapter specific knowledge. The *real* solution, is to deprecate this behavior entirely. The only reason we need it is because the `:case_sensitive` option for `validates_uniqueness_of` is documented as "this option is ignored for non-strings". It makes no sense for us to do that. If the type can't be compared in a case insensitive way, the user shouldn't tell us to do case insensitive comparison.
* Fix validations on child record when record parent has validate: falseeileencodes2015-02-013-0/+14
| | | | | | | | | | | | | | Fixes #17621. This 5 year old (or older) issue causes validations to fire when a parent record has `validate: false` option and a child record is saved. It's not the responsibility of the model to validate an associated object unless the object was created or modified by the parent. Clean up tests related to validations `assert_nothing_raised` is not benefiting us in these tests Corrected spelling of "respects" It's better to use `assert_not_operator` over `assert !r.valid`
* Remove most type related predicates from `Column`Sean Griffin2015-01-301-2/+3
| | | | | | Remaining are `limit`, `precision`, `scale`, and `type` (the symbol version). These will remain on the column, since they mirror the options to the `column` method in the schema definition DSL
* Don't rely on the column for type information in uniquness validationsSean Griffin2015-01-011-1/+2
| | | | The validator has access to richer type information
* AR specific length validator to respect `marked_for_destruction`.Yves Senn2014-12-301-0/+21
| | | | | | | | Closes #7247. Conflicts: activerecord/CHANGELOG.md activerecord/test/models/owner.rb
* Remove all cases of manuallly wrapping `Arel::Nodes::Quoted`Sean Griffin2014-12-291-1/+0
| | | | | | | | | | This is no longer required now that we are injecting a type caster object into the Arel table, with the exception of uniqueness validations. Since it calls `ConnectionAdapter#type_cast`, the value has already been cast for the database. We don't want Arel to attempt to cast it further, so we need to continue wrapping it in a quoted node. This can potentially go away when this validator is refactored to make better use of `where` or the predicate builder.
* Go through normal `where` logic in uniqueness validationSean Griffin2014-12-261-4/+6
| | | | | | | This code could use some much heavier refactoring. It looks like `build_relation` duplicates most of the logic of `Relation#where` and `PredicateBuilder` with regards to handling associations and attribute aliases
* We don't need to cast the value a second time in uniqueness validationsSean Griffin2014-12-261-0/+1
| | | | | | | Part of the larger refactoring to remove type casting from Arel. Since we've already cast the value a few lines above, we don't need to re-cast it later. We can inform Arel of this by wrapping it in an `Arel::Nodes::Quoted`, which will no longer be required in Rails 5.1
* Correctly ignore `case_sensitive` for UUID uniqueness validationSean Griffin2014-12-261-1/+1
| | | | | | | | I think we should deprecate this behavior and just error if you tell us to do a case insensitive comparison for types which are not case sensitive. Partially reverts 35592307 Fixes #18195
* Pass symbol as an argument instead of a blockErik Michaels-Ober2014-11-291-1/+1
|
* Improve the performance of reading attributesSean Griffin2014-11-181-1/+1
| | | | | | | We added a comparison to "id", and call to `self.class.primary_key` a *lot*. We also have performance hits from `&block` all over the place. We skip the check in a new method, in order to avoid breaking the behavior of `read_attribute`
* Add a note on custom validation contexts.Justin Weiss2014-08-052-6/+10
| | | | | | | | | The documentation on `:on` for validations was inconsistent, and most only referenced the `:create` and `:update` contexts. I fixed those to be consistent with the documentation on `AM::Validations.validates`, which seemed to have the best docs. [ci skip]
* [ci skip] fix doc typo for validates_uniqueness_ofSatoru Yamasaki2014-07-291-1/+1
|
* Remove the `text?` predicate from the type objectsSean Griffin2014-07-061-2/+4
| | | | | | | This was only used for uniqueness validations. The first usage was in conjunction with `limit`. Types which cast to string, but are not considered text cannot have a limit. The second case was only with an explicit `:case_sensitive => true` option given by the user.
* Don't rely on the column for type casting reflectionsSean Griffin2014-06-181-1/+1
|
* Remove most code related to serialized propertiesSean Griffin2014-06-011-7/+0
| | | | | | | | | | | Nearly completely implemented in terms of custom properties. `_before_type_cast` now stores the raw serialized string consistently, which removes the need to keep track of "state". The following is now consistently true: - `model.serialized == model.reload.serialized` - A model can be dumped and loaded infinitely without changing - A model can be saved and reloaded infinitely without changing
* Merge pull request #15210 from arthurnn/fix_hbtm_reflectionArthur Neves2014-05-242-3/+3
| | | | | | | | | Fix habtm reflection Conflicts: activerecord/CHANGELOG.md activerecord/lib/active_record/counter_cache.rb activerecord/lib/active_record/reflection.rb activerecord/test/cases/reflection_test.rb
* Follow up to bbe7fe41 to fix enum leakage across classes.Godfrey Chan2014-04-071-1/+1
| | | | | | | | The original attempt didn't really fix the problem and wasn't testing the problematic area. This commit corrected those issues in the original commit. Also removed the private `enum_mapping_for` method. As `defined_enums` is now a method, this method doesn't provide much value anymore.
* Merge pull request #13040 from kamipo/case_sensitive_comparisonRafael Mendonça França2014-03-121-2/+1
|\ | | | | | | | | | | | | Only use BINARY for mysql case sensitive uniqueness check when column has a case insensitive collation. Conflicts: activerecord/CHANGELOG.md
| * Only use BINARY for mysql case sensitive uniqueness check when column has a ↵Ryuta Kamizono2013-11-261-2/+1
| | | | | | | | case insensitive collation.