Remove workaround for non-lazy serialize in tests

`serialize` is now lazy, so the workaround is no longer needed.
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.