Introduce an Attribute object to handle the type casting dance

Depends on #15429 and includes the changes from that PR as well. 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, and reduce allocations
Benchmark showed `defined?` is faster when a value is falsy, even when the type does no work but check if it got `nil`.  I do have an explicit test for this case, I'll add a comment as well.