aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/type
Commit message (Collapse)AuthorAgeFilesLines
* Fixing numeric attrs when set to same negative valueDaniel Fox2014-12-231-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This bug occurs when an attribute of an ActiveRecord model is an ActiveRecord::Type::Integer type or a ActiveRecord::Type::Decimal type (or any other type that includes the ActiveRecord::Type::Numeric module. When the value of the attribute is negative and is set to the same negative value, it is marked as changed. Take the following example of a Person model with the integer attribute age: class Person < ActiveRecord::Base # age :integer(4) end The following will produce the error: person = Person.new(age: -1) person.age = -1 person.changes => { "age" => [-1, -1] } person.age_changed? => true The problematic line is here: module ActiveRecord module Type module Numeric ... def non_numeric_string?(value) # 'wibble'.to_i will give zero, we want to make sure # that we aren't marking int zero to string zero as # changed. value.to_s !~ /\A\d+\.?\d*\z/ end end end end The regex match doesn't accept numbers with a leading '-'.
* Correctly handle Float -> BigDecimal with unspecified precisionSean Griffin2014-12-221-1/+9
| | | | Fixes #18122
* Fix undesirable RangeError by Type::Integer. Add Type::UnsignedInteger.Ryuta Kamizono2014-12-122-1/+20
|
* Fix out of range error messageRyuta Kamizono2014-11-251-1/+1
|
* Ensure the type map's cache is thread safeSean Griffin2014-11-241-3/+7
| | | | | Thanks to @thedarkone for pointing out that an instance of this object is used in a shared context.
* Reintroduce cache with testsSean Griffin2014-11-192-14/+24
|
* Add tests for `TypeMap#fetch` and push up to `TypeMap`Sean Griffin2014-11-192-5/+5
| | | | | | | It doesn't make sense for the subclass to implement this method, and not have it on the parent. We can also DRY up the implementation of `#lookup` to be defined in terms of fetch, which will give us a single point of entry
* Revert "PERF: optimise type lookup to avoid invoking procs"Sean Griffin2014-11-191-19/+1
| | | | This reverts commit da99a2a2982d35f670ad9647463e09bfe9032b70.
* Speed up integer casting from DBSean Griffin2014-11-181-0/+5
| | | | | | | | We don't have the check the range when the value is coming from the DB, so override type_cast_from_database to short-circuit the extra work. The difference is huge but the absolute gain is quite small. That being said this is a hotspot and it showed up on the radar when benchmarking discourse.
* Revert "[PERF] Speed up integer type casting from DB"Godfrey Chan2014-11-171-4/+1
| | | | | | This reverts commit 6f7910a and 52c70d4. Query params are type cased through the same method, so this approach doesn't work.
* :nail_care: Put escape clause first, keeps @sgrif happy :grin:Godfrey Chan2014-11-171-1/+2
| | | | See comment on 6f7910a
* [PERF] Speed up integer type casting from DBGodfrey Chan2014-11-171-1/+3
| | | | | | | | | | | | | | | | | | | We don't have the check the range when the value is coming from the DB, so override type_cast_from_database to short-circuit the extra work. type_cast_from_database (small) 3437507.5 (±29.2%) i/s - 14223135 in 4.996973s type_cast_from_database (large) 3158588.7 (±28.3%) i/s - 13265628 in 4.992121s type_cast (small) 481984.8 (±14.2%) i/s - 2352012 in 5.005694s type_cast (large) 477331.8 (±14.2%) i/s - 2332824 in 5.012365s Comparison: type_cast_from_database (small): 3437507.5 i/s type_cast_from_database (large): 3158588.7 i/s - 1.09x slower type_cast (small): 481984.8 i/s - 7.13x slower type_cast (large): 477331.8 i/s - 7.20x slower The difference is huge but the absolute gain is quite small. That being said this is a hotspot and it showed up on the radar when benchmarking discourse.
* PERF: optimise type lookup to avoid invoking procsSam2014-11-171-1/+19
|
* Use `DelegateClass` instead of `SimpleDelegator` for type decoratorsSean Griffin2014-11-141-1/+1
| | | | There is a significant performance difference between the two. Closes
* Revert the behavior of booleans in string columns to that of 4.1Sean Griffin2014-11-091-4/+4
| | | | | | | | | | | | | | | | | | | | | Why are people assigning booleans to string columns? >_> We unintentionally changed the behavior on Sqlite3 and PostgreSQL. Boolean values should cast to the database's representation of true and false. This is 't' and 'f' by default, and "1" and "0" on Mysql. The implementation to make the connection adapter specific behavior is hacky at best, and should be re-visted once we decide how we actually want to separate the concerns related to things that should change based on the database adapter. That said, this isn't something I'd expect to change based on my database adapter. We're storing a string, so the way the database represents a boolean should be irrelevant. It also seems strange for us to give booleans special behavior at all in string columns. Why is `to_s` not sufficient? It's inconsistent and confusing. Perhaps we should consider deprecating in the future. Fixes #17571
* Use the correct values for int max and minSean Griffin2014-10-311-9/+13
| | | | | We had accidentally gone one power of two too far. In addition, we need to handle minimum values as well as the maximum.
* Treat strings greater than int max value as out of rangeSean Griffin2014-10-313-3/+35
| | | | | | | | | | | Sufficiently large integers cause `find` and `find_by` to raise `StatementInvalid` instead of `RecordNotFound` or just returning `nil`. Given that we can't cast to `nil` for `Integer` like we would with junk data for other types, we raise a `RangeError` instead, and rescue in places where it would be highly unexpected to get an exception from casting. Fixes #17380
* edit pass over all warningsXavier Noria2014-10-281-3/+7
| | | | | | | | | | | | | | | This patch uniformizes warning messages. I used the most common style already present in the code base: * Capitalize the first word. * End the message with a full stop. * "Rails 5" instead of "Rails 5.0". * Backticks for method names and inline code. Also, converted a few long strings into the new heredoc convention.
* Fix typo in error message when non-boolean value is assigned to boolean columnPrathamesh Sonpatki2014-10-261-1/+1
|
* Add a deprecation warning for abiguous boolean valuesSean Griffin2014-10-161-1/+8
| | | | | | | | | | | In Rails 5.0, we'd like to change the behavior of boolean columns in Rails to be closer to Ruby's semantics. Currently we have a small set of values which are "truthy", and all others are "falsy". In Rails 5.0, we will reverse this to have a small number of values which are "falsy", and all others will become "truthy". In the interim, all values which are ambiguous must emit a deprecation warning.
* Allow YAML serialization when using TZ aware attributesSean Griffin2014-09-172-3/+17
|
* Correctly detect mutation on serialized columns mapping to binarySean Griffin2014-08-272-0/+15
| | | | Fixes #16701
* Implement `==` on `Type::Value` and `Attribute`Sean Griffin2014-08-151-0/+7
| | | | | This was a small self contained piece of the refactoring that I am working on, which required these objects to be comparable.
* [ci skip] fix spelling of overrideAkshay Vishnoi2014-08-131-2/+2
|
* Merge pull request #16333 from ↵Yves Senn2014-08-041-4/+17
|\ | | | | | | | | | | | | | | | | joker1007/fix_decimal_cast_from_float_with_large_precision Fix type casting to Decimal from Float with large precision Conflicts: activerecord/CHANGELOG.md
| * Fix type casting to Decimal from Float with ...joker10072014-08-011-4/+17
| | | | | | | | | | When I defines large precision column at RDBMS, I assigns float value, raise ArgumentError (precision too large).
* | Rename method for clarityCarlos Antonio da Silva2014-07-311-3/+3
|/ | | | Ruby generally does not use the is_* prefix on predicate methods.
* Prefer if/else for this caseRafael Mendonça França2014-07-171-3/+2
| | | | | One of the branches is using a proc to check if the value respond_to a method so it is better to not do case comparations
* Fix decimal_test module and add new test for object responding to to_dMariano Valles2014-07-161-1/+0
|
* Fix case statement to use ::Numeric and ::StringMariano Valles2014-07-161-1/+1
|
* Change class evaluation for Rationals in cast_valueMariano Valles2014-07-161-4/+6
|
* Fix rational to decimal on type_cast_from_userMariano Valles2014-07-161-1/+3
|
* Remove the `text?` predicate from the type objectsSean Griffin2014-07-062-8/+0
| | | | | | | 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.
* active_record: Type cast booleans and durations for string columns.Dylan Thacker-Smith2014-07-062-2/+4
|
* Remove unneccessary special case for money in quotingSean Griffin2014-07-031-4/+4
|
* Merge pull request #15788 from sgrif/sg-mutable-stringsRafael Mendonça França2014-06-271-1/+16
|\ | | | | | | Detect in-place modifications on Strings
| * Detect in-place modifications on StringsSean Griffin2014-06-171-1/+16
| |
* | Doc pass for `Type::Value` [ci skip]Sean Griffin2014-06-242-23/+43
| |
* | Always assume strings with non-numeric characters change numeric typesSean Griffin2014-06-241-3/+3
| | | | | | | | | | | | | | | | We previously only did this if the old value was zero, to make sure numericality validations run and failed if the user gave 'wibble' as the value, which would be type cast to 0. However, numericality validations will fail if there are any non-numeric characters in the string, so 5 -> '5wibble' should also be marked as changed.
* | add missing `:nodoc:` for recent refactorings. [ci skip]Yves Senn2014-06-242-2/+2
| | | | | | | | | | | | | | | | | | | | Adding `# :nodoc:` to the parent `class` / `module` is not going to ignore nested classes or modules. There is a modifier `# :nodoc: all` but sadly the containing class or module will continue to be in the docs. /cc @sgrif
* | Small typoAnton Cherepanov2014-06-231-1/+1
| |
* | Further simplify `changed?` conditional for numeric typesSean Griffin2014-06-191-12/+6
|/ | | | | | | `Type::Integer.new.type_cast('') # => nil`, we do not need a special case to handle this, `nil => ''` already returns false. The only case we need to handle is `0 => 'wibble'` should be changed, while `0 => '0'` should not.
* Move array database type casting to the Array typeSean Griffin2014-06-171-0/+10
| | | | | | | | | The case where we have a column object, but don't have a type cast method involves type casting the default value when changing the schema. We get one of the column definition structs instead. That is a case that I'm trying to remove overall, but in the short term, we can achieve the same behavior without needing to pass the adapter to the array type by creating a fake type that proxies to the adapter.
* Remove `serialized?` from the type interfaceSean Griffin2014-06-132-8/+0
|
* Detect in-place changes on mutable AR attributesSean Griffin2014-06-133-4/+22
| | | | | | We have several mutable types on Active Record now. (Serialized, JSON, HStore). We need to be able to detect if these have been modified in place.
* Keep the types of virtual columns after yaml serializationSean Griffin2014-06-101-0/+11
| | | | | On MySQL and PostgreSQL, the adapter does not type cast virtual columns for us.
* Rename `type_cast` to `type_cast_from_database`Sean Griffin2014-06-092-7/+10
| | | | | | | | In some cases there is a difference between the two, we should always be doing one or the other. For convenience, `type_cast` is still a private method on type, so new types that do not need different behavior don't need to implement two methods, but it has been moved to private so it cannot be used accidentally.
* Make `_before_type_cast` actually be before type castSean Griffin2014-06-093-8/+19
| | | | | | | | | | | | | - The following is now true for all types, all the time - `model.attribute_before_type_cast == given_value` - `model.attribute == model.save_and_reload.attribute` - `model.attribute == model.dup.attribute` - `model.attribute == YAML.load(YAML.dump(model)).attribute` - Removes the remaining types implementing `type_cast_for_write` - Simplifies the implementation of time zone aware attributes - Brings tz aware attributes closer to being implemented as an attribute decorator - Adds additional point of control for custom types
* Do not type cast twice on attribute assignmentSean Griffin2014-06-073-9/+5
| | | | | | | | | | | | | The definition of `write_attribute` in dirty checking ultimately leads to the columns calling `type_cast` on the value to perform the comparison. However, this is a potentially expensive computation that we cache when it occurs in `read_attribute`. The only case that we need the non-type-cast form is for numeric, so we pass that through as well (something I'm looking to remove in the future). This also reduces the number of places that manually access various stages in an attribute's type casting lifecycle, which will aid in one of the larger refactorings that I'm working on.
* Removed unused `klass` definitions from typesSean Griffin2014-06-066-21/+0
| | | | Only `Date` and `Time` are handled.