0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Posted at
[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が呼ばれクエリが発行されて、無事インスタンス化

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?