1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00
Commit graph

13 commits

Author SHA1 Message Date
Sean Griffin
3a551b9777 All subclasses of Attribute should be private constants 2015-01-27 13:08:07 -07:00
Sean Griffin
be9b68038e Introduce ActiveRecord::Base#accessed_fields
This method can be used to see all of the fields on a model which have
been read. This can be useful during development mode to quickly find
out which fields need to be selected. For performance critical pages, if
you are not using all of the fields of a database, an easy performance
win is only selecting the fields which you need. By calling this method
at the end of a controller action, it's easy to determine which fields
need to be selected.

While writing this, I also noticed a place for an easy performance win
internally which I had been wanting to introduce. You cannot mutate a
field which you have not read. Therefore, we can skip the calculation of
in place changes if we have never read from the field. This can
significantly speed up methods like `#changed?` if any of the fields
have an expensive mutable type (like `serialize`)

```
Calculating -------------------------------------
 #changed? with serialized column (before)
                       391.000  i/100ms
 #changed? with serialized column (after)
                         1.514k i/100ms
-------------------------------------------------
 #changed? with serialized column (before)
                          4.243k (± 3.7%) i/s -     21.505k
 #changed? with serialized column (after)
                         16.789k (± 3.2%) i/s -     84.784k
```
2015-01-20 14:42:15 -07:00
Sean Griffin
d8e710410e Only use the _before_type_cast in the form when from user input
While we don't want to change the form input when validations fail,
blindly using `_before_type_cast` will cause the input to display the
wrong data for any type which does additional work on database values.
2015-01-14 17:08:25 -07:00
Sean Griffin
dd8b5fb9d3 update_column take ruby-land input, not database-land input
In the case of serialized columns, we would expect the unserialized
value as input, not the serialized value. The original issue which made
this distinction, #14163, introduced a bug. If you passed serialized
input to the method, it would double serialize when it was sent to the
database. You would see the wrong input upon reloading, or get an error
if you had a specific type on the serialized column.

To put it another way, `update_column` is a special case of
`update_all`, which would take `['a']` and not `['a'].to_yaml`, but you
would not pass data from `params` to it.

Fixes #18037
2014-12-16 15:23:05 -07:00
Sean Griffin
877ea784e4 Implement _was and changes for in-place mutations of AR attributes 2014-08-16 23:08:41 -07:00
Sean Griffin
bc153cff91 Implement == on Type::Value and Attribute
This was a small self contained piece of the refactoring that I am
working on, which required these objects to be comparable.
2014-08-15 13:37:53 -06:00
Sean Griffin
3bc314e658 Move writing unknown column exception to null attribute
Making this change revealed several subtle bugs related to models with
no primary key, and anonymous classes. These have been fixed as well,
with regression tests added.
2014-06-26 09:43:35 -06:00
Sean Griffin
bb7bc499e5 Attribute should know about its name
This allows using polymorphism for the uninitialized attributes raising
an exception behavior.
2014-06-26 07:18:21 -06:00
Sean Griffin
14b1208dd3 Encapsulate the creation of Attribute objects
This will make it less painful to add additional properties, which
should persist across writes, such as `name`.

Conflicts:
	activerecord/lib/active_record/attribute_set.rb
2014-06-26 06:45:57 -03:00
Sean Griffin
a89f8a922d Move behavior of read_attribute to AttributeSet
Moved `Builder` to its own file, as it started looking very weird once I
added private methods to the `AttributeSet` class and the `Builder`
class started to grow.

Would like to refactor `fetch_value` to change to

```ruby
self[name].value(&block)
```

But that requires the attributes to know about their name, which they
currently do not.
2014-06-25 08:51:15 -06:00
Yves Senn
b27e856d3f add missing :nodoc: for recent refactorings. [ci skip]
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
2014-06-24 12:30:21 +02:00
Sean Griffin
218105f58e Refactor in-place dirty checking to use the attribute object 2014-06-16 11:20:55 -06:00
Sean Griffin
6f08db05c0 Introduce an Attribute object to handle the type casting dance
There's a lot more that can be moved to these, but this felt like a good
place to introduce the object. Plans are:

- Remove all knowledge of type casting from the columns, beyond a
  reference to the cast_type
- Move type_cast_for_database to these objects
- Potentially make them mutable, introduce a state machine, and have
  dirty checking handled here as well
- Move `attribute`, `decorate_attribute`, and anything else that
  modifies types to mess with this object, not the columns hash
- Introduce a collection object to manage these, reduce allocations, and
  not require serializing the types
2014-06-13 10:20:54 -06:00