Open halostatue opened 8 years ago
Nice work!
I packaged it into a plugin for anyone interested:
module Sequel
module Plugins
module GlobalId
# Add Global ID support for Sequel::Models
# Code comes @halostatue from https://github.com/TalentBox/sequel-rails/issues/111
def self.apply(base, *)
base.send(:include, ::GlobalID::Identification)
GlobalID::Locator::BaseLocator.prepend SequelBaseLocator
end
module SequelBaseLocator
def locate(gid)
if defined?(::Sequel::Model) && gid.model_class < Sequel::Model
gid.model_class.with_pk!(gid.model_id)
else
super
end
end
private
def find_records(model_class, ids, options)
if defined?(::Sequel::Model) && model_class < Sequel::Model
model_class.where(model_class.primary_key => ids).tap do |result|
if !options[:ignore_missing] && result.count < ids.size
fail Sequel::NoMatchingRow
end
end.all
else
super
end
end
end
end
end
end
For anyone else finding this, the API for locate
has changed a little: https://github.com/rails/globalid#custom-app-locator
The new plugin would be something like:
module Sequel
module Plugins
module GlobalId
# Add Global ID support for Sequel::Models
# Code comes @halostatue from https://github.com/TalentBox/sequel-rails/issues/111
def self.apply(base, *)
base.send(:include, ::GlobalID::Identification)
GlobalID::Locator::BaseLocator.prepend SequelBaseLocator
end
module SequelBaseLocator
def locate(gid, options = {})
if defined?(::Sequel::Model) && gid.model_class < Sequel::Model
gid.model_class.with_pk!(gid.model_id)
else
super
end
end
private
def find_records(model_class, ids, options)
if defined?(::Sequel::Model) && model_class < Sequel::Model
model_class.where(model_class.primary_key => ids).tap do |result|
if !options[:ignore_missing] && result.count < ids.size
fail Sequel::NoMatchingRow
end
end.all
else
super
end
end
end
end
end
end
Sequel doesn’t follow the same protocol as ActiveRecord, even when ActiveModel compliant (or so it seems). I’ve come up with what looks like the right level of monkey-patching for this, and can turn this into a real patch (with tests) for GlobalID if there is interest. The changes are only necessary in
GlobalID::Locator::BaseLocator
for#locate
and#find_records
.The only other change is including GlobalID::Identification into Sequel::Model, but in my basic testing, these changes create the same result as AR-backed GlobalID, mod the appropriate exceptions. If we want to make a real patch out of this, then we should probably make a plugin so that we can do
Sequel::Model.plugin :globalid
for explicit opt-in.This has also been opened as rails/globalid#87.