Remove workaround for non-lazy serialize in tests

`serialize` is now lazy, so the workaround is no longer needed.
Refactor determination of max updated timestamp

`[].max # => nil`
Make `_before_type_cast` actually be before type cast

- 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 try to set the foreign_key again on has_many through

Integration tests are inside protected_attributes test suite.

Fixes #15496
Fixes rails/protected_attributes#35
Merge pull request #15591 from sgrif/sg-rm-write-attribute

Make `_before_type_cast` actually be before type cast
Merge pull request #15587 from sgrif/sg-remove-workaround

Remove workaround for non-lazy serialize in tests
Use an actual identity type in AR::Result#identity_type

We should be able to rely on this object implenting the full type
interface.
Merge pull request #15586 from sgrif/sg-identity-type

Use an actual identity type in AR::Result#identity_type
Rename `type_cast` to `type_cast_from_database`

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.
Merge pull request #15592 from sgrif/sg-type-cast-from-database

Rename `type_cast` to `type_cast_from_database`
Timestamp values should be present on callbacks

This reverts commit dd3ea17191e316aeebddaa7b176f6cfeee7a6365 and add a
regression test.

Fixes #15418
Fix bug that make HashWithIndifferentAccess work differently of Hash

Before HashWithIndifferentAccess were doing deep_dup of the inner hashes
when Hash doesn't do. Now both are behaving in the same way.
add has_one? method and reuse instead of checking macro

Instead of checking for `macro == :has_one` throughout the
codebase we can create a `has_one?` method to match the `belongs_to?`,
`polymorphic?` and other methods.
Abstract away use of HABTM macro

By having the `:has_and_belongs_to_many` macro in the `@collection`
we are punishing `:has_many` associations because it has to allocate
the array and check the macro.

@collection is returned to `macro == :has_many` and a new reflection
class `HABTMReflection` is created to handle this case instead.
Merge pull request #15595 from eileencodes/abstract-away-habtm-macro

Abstract away use of HABTM macro
Merge pull request #15596 from eileencodes/add-has_one-method-and-reuse

add has_one? method and reuse instead of checking macro
reuse available collection? check instead of macro

Reflection has an available method that is used to check if the
reflection is a collection. Any :has_many macro is considered a
collection and `collection?` should be used instead of
`macro == :has_many`.
Merge pull request #15597 from eileencodes/reuse-available-collection-methods

reuse available collection? check instead of macro
Use HasAndBelongsToMany instead of HABTM
Merge pull request #15599 from arthurnn/HABTMAssociation

Use HasAndBelongsToMany instead of HABTM