ActiveRecordがglobalidになって帰ってくるまで

```
[34] pry(main)> $ User.last.to_global_id

def to_global_id(options = {})
  GlobalID.create(self, options)
end
```

```
[35] pry(main)> $ GlobalID

class GlobalID
  class << self
    attr_reader :app

    def create(model, options = {})
      if app = options.fetch(:app) { GlobalID.app }
        params = options.except(:app, :verifier, :for)
        new URI::GID.create(app, model, params), options
      else
        raise ArgumentError, 'An app is required to create a GlobalID. ' \
          'Pass the :app option or set the default GlobalID.app.'
      end
    end

...

  def initialize(gid, options = {})
    @uri = gid.is_a?(URI::GID) ? gid : URI::GID.parse(gid)
  end

```

```
[37] pry(main)> $ URI::GID

class GID < Generic
  class << self
   def create(app, model, params = nil)
      build app: app, model_name: model.class.name, model_id: model.id, params: params
    end

    def build(args)
      parts = Util.make_components_hash(self, args)
      parts[:host] = parts[:app]
      parts[:path] = "/#{parts[:model_name]}/#{CGI.escape(parts[:model_id].to_s)}"

      if parts[:params] && !parts[:params].empty?
        parts[:query] = URI.encode_www_form(parts[:params])
      end

      super parts
    end


```

```
[42] pry(main)> $ URI::GID::Generic
 class Generic
   def self.build(args)
      if args.kind_of?(Array) &&
          args.size == ::URI::Generic::COMPONENT.size
        tmp = args.dup
      elsif args.kind_of?(Hash)
        tmp = ::URI::Generic::COMPONENT.collect do |c|
          if args.include?(c)
            args[c]
          else
            nil
          end
        end
      else
        component = self.class.component rescue ::URI::Generic::COMPONENT
        raise ArgumentError,
        "expected Array of or Hash of components of #{self.class} (#{component.join(', ')})"
      end

      tmp << nil
      tmp << true
      return self.new(*tmp)
    end

 def initialize(scheme,
                   userinfo, host, port, registry,
                   path, opaque,
                   query,
                   fragment,
                   parser = DEFAULT_PARSER,
                   arg_check = false)
      @scheme = nil
      @user = nil
      @password = nil
      @host = nil
      @port = nil
      @path = nil
      @query = nil
      @opaque = nil
      @fragment = nil
      @parser = parser == DEFAULT_PARSER ? nil : parser

      if arg_check
        self.scheme = scheme
        self.userinfo = userinfo
        self.hostname = host
        self.port = port
        self.path = path
        self.query = query
        self.opaque = opaque
        self.fragment = fragment
      else
        self.set_scheme(scheme)
        self.set_userinfo(userinfo)
        self.set_host(host)
        self.set_port(port)
        self.set_path(path)
        self.query = query
        self.set_opaque(opaque)
        self.fragment=(fragment)
      end
      if registry
        raise InvalidURIError,
          "the scheme #{@scheme} does not accept registry part: #{registry} (or bad hostname?)"
      end

      @scheme&.freeze
      self.set_path('') if !@path && !@opaque # (see RFC2396 Section 5.2)
      self.set_port(self.default_port) if self.default_port && !@port
    end

```


戻ってきてGlobalID#to_s

```
[48] pry(main)> $ GlobalID#to_s

delegate :app, :model_name, :model_id, :params, :to_s, to: :uri

[47] pry(main)> $ URI::GID#to_s

def to_s
  # Implement #to_s to avoid no implicit conversion of nil into string when path is nil
  "gid://#{app}#{path}#{'?' + query if query}"
end
```

これがよく見る文字列になるまで
この文字列がARクラスのインスタンスに戻るまでは

```
[50] pry(main)> $ GlobalID::Locator.locate

def locate(gid, options = {})
  if gid = GlobalID.parse(gid)
    locator_for(gid).locate gid if find_allowed?(gid.model_class, options[:only])
  end
end

```

locator_forでBaseLocatorのサブクラスのどれかが帰って、

```
[61] pry(main)> $ GlobalID::Locator::BaseLocator#locate


def locate(gid)
  gid.model_class.find gid.model_id
end
```

ここでAR.findが呼ばれクエリが発行されて、無事インスタンス化