zendesk/active_record_shards — pull request #5 by lukkry (2013-08-25 21:12:15+00:00)
Title: Rails 4

This PR adds support for Rails 4.

I try to highlight the biggest changes and describe how I approached them, it's likely going to be a long PR message, so bear with me ;)
* `ConnectionSpecification` lives in a different namespace, so `ActiveRecordShards::ConnectionSpecification` was introduced.

```ruby
# lib/active_record_shards.rb
if ActiveRecord::VERSION::STRING >= "4.0.0"
ActiveRecordShards::ConnectionSpecification = ActiveRecord::ConnectionAdapters::ConnectionSpecification
else
ActiveRecordShards::ConnectionSpecification = ActiveRecord::Base::ConnectionSpecification
end
```

* `ConnectionHandler` was slightly redesigned and `klass.name` is called more often now (it's a key in `@class_to_pool` => all the methods where it's used are currently overrided and `klass.connection_pool_name` is used instead). If we want to stick with the current approach we'll have to override many more methods from `ConnectionHandler`. Therefore, I created `ActiveRecordDecorator` to avoid it. This class decorates `ActiveRecord::Base` object and returns connection pool name instead of its name. It allows us to override `ConnectionHandler` methods without changing or copying any logic:

```ruby
# lib/active_record_shards/connection_pool.rb
def establish_connection_with_connection_pool_name(owner, spec)
owner = ActiveRecordDecorator.new(owner)
establish_connection_without_connection_pool_name(owner, spec)
end
alias_method_chain :establish_connection, :connection_pool_name
```

* `with_scope` is depracated => `scoping` is used instead

```ruby
# lib/active_record_shards/connection_switcher.rb
if ActiveRecord::VERSION::MAJOR == 2
with_scope({:find => {:readonly => true}}, &block)
else
readonly.scoping(&block)
end
```

* ConnectionHandler#connection_pools is depracated, it is fairly simple, so I've just copy-pasted it

```ruby
# lib/active_record_shards/connection_switcher.rb
def connected_to_shard?
if ActiveRecord::VERSION::MAJOR == 4
specs_to_pools = Hash[connection_handler.connection_pool_list.map { |pool| [pool.spec, pool] }]
else
specs_to_pools = connection_handler.connection_pools
end

specs_to_pools.has_key?(connection_pool_key)
end
```

Let me know what you think, appreciate any feedback! ;)