Skip to content

Commit

Permalink
Merge pull request #9 from yuemori/feature/support_instance_method
Browse files Browse the repository at this point in the history
Implement distkey support to instance method
  • Loading branch information
yuemori authored Jul 31, 2016
2 parents 15a07f2 + caf62f0 commit 52d2e18
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
20 changes: 17 additions & 3 deletions lib/activerecord/shard_for/model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ def shard_for(key)
# @raise [ActiveRecord::ShardFor::MissingDistkeyAttribute]
def put!(attributes)
raise '`distkey` is not defined. Use `def_distkey`.' unless distkey

@before_put_callback.call(attributes) if defined?(@before_put_callback) && @before_put_callback
key = attributes[distkey]

raise ActiveRecord::ShardFor::MissingDistkeyAttribute unless key || attributes[distkey.to_s]
key = fetch_distkey_from_attributes(attributes)

raise ActiveRecord::ShardFor::MissingDistkeyAttribute unless key

shard_for(key).create!(attributes)
end
Expand Down Expand Up @@ -139,6 +139,20 @@ def replicates_with(mapping)
def switch(role_name, &block)
replication_mapping.switch(self, role_name, &block)
end

private

# @param [Hash] attributes
# @return [Object or nil] distkey
def fetch_distkey_from_attributes(attributes)
key = attributes[distkey] || attributes[distkey.to_s]
return key if key

instance = all_shards.first.new(attributes)
return unless instance.respond_to?(distkey)

instance.send(distkey)
end
end
end
end
Expand Down
26 changes: 26 additions & 0 deletions spec/activerecord/shard_for/model_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,22 @@ def self.generate_name
end
end

let!(:another_model) do
Class.new(ActiveRecord::Base) do
def self.name
'User'
end

include ActiveRecord::ShardFor::Model
use_cluster :character, :distkey
def_distkey :shard_no

def shard_no
1
end
end
end

let(:user_attributes) { { name: 'Alice', email: '[email protected]' } }

describe '.put!' do
Expand All @@ -39,6 +55,16 @@ def self.generate_name
.to raise_error(ActiveRecord::ShardFor::MissingDistkeyAttribute)
end
end

context 'distkey be specify instance method' do
before { another_model.put!(user_attributes) }

it 'creates new record into shard 1' do
record = another_model.using(1).find_by(email: user_attributes[:email])
expect(record).to be_a(another_model)
expect(record).not_to be_nil
end
end
end

describe '.before_put' do
Expand Down

0 comments on commit 52d2e18

Please sign in to comment.