Most of the support here is in implementing how to correctly substitute
multiple values in place of one, for composite caes. In composite cases,
it's not sufficient to hash a label into a single integer value.
Instead, we build an API that accepts a single label, and a list of
columns that we'd like to map to. The algorithm used internally is very
similar to #identify, with an additional bit shift and modulo to cycle
the hash and ensure it doesn't exceed a max.
Given a model associated with a composite primary key by `id` attribute,
for example:
```ruby
Order.primary_key = [:shop_id, :id]
OrderAgreement.primary_key = :id
Order.has_many :order_agreements, primary_key: :id
```
Accessing the association should perform queries using
the `id` attribute value and not the `id` as Order's composite primary key.
```ruby
order = Order.last # => #<Order id: 1, shop_id: 2>
order.order_agreements.to_a
```
Given a model with a composite primary key:
```ruby
class Order < ActiveRecord::Base
self.primary_key = [:shop_id, :id]
end
```
`ActiveRecord::Base#id` method will return an array of values for every
column of the primary key.
```ruby
order = Order.create!(shop_id: 1, id: 2)
order.id # => [1, 2]
```
The `id` column is accessible through the `read_attribute` method:
```ruby
order.read_attribute(:id) # => 2
```