Module: GraphQL::Client::ViewModule

Defined in:
lib/graphql/client/view_module.rb

Overview

Allows a magic namespace to map to app/views/*/.erb files to retrieve statically defined GraphQL definitions.

# app/views/users/show.html.erb
<%grapql
  fragment UserFragment on User { }
%>

# Loads graphql section from app/views/users/show.html.erb
Views::Users::Show::UserFragment

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#clientObject

Returns the value of attribute client.



20
21
22
# File 'lib/graphql/client/view_module.rb', line 20

def client
  @client
end

#pathObject

Public: Source location that defined the Module.

Returns absolute String path under app/views.



94
95
96
# File 'lib/graphql/client/view_module.rb', line 94

def path
  @path
end

Class Method Details

.valid_constant_name?(name) ⇒ Boolean

Internal: Check if name is a valid Ruby constant identifier.

name - String or Symbol constant name

Examples

valid_constant_name?("Foo") #=> true
valid_constant_name?("404") #=> false

Returns true if name is a valid constant, otherwise false if name would result in a “NameError: wrong constant name”.

Returns:

  • (Boolean)


60
61
62
# File 'lib/graphql/client/view_module.rb', line 60

def self.valid_constant_name?(name)
  name.to_s =~ /^[A-Z][a-zA-Z0-9_]*$/
end

Instance Method Details

#const_missing(name) ⇒ Object

Public: Implement constant missing hook to autoload View ERB statics.

name - String or Symbol constant name

Returns module or raises NameError if missing.



142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/graphql/client/view_module.rb', line 142

def const_missing(name)
  path = const_path(name)

  if path
    mod = load_module(path)
    const_set(name, mod)
    mod.unloadable
    mod
  else
    super
  end
end

#const_path(name) ⇒ Object

Internal: Detect source location for constant name.

name - String or Symbol constant name

Examples

Views.const_path(:Users) #=> "app/views/users"
Views::Users.const_path(:Show) #=> "app/views/users/show.html.erb"
Views::Users.const_path(:Profile) #=> "app/views/users/_profile.html.erb"

Returns String absolute path to file, otherwise nil.



107
108
109
110
# File 'lib/graphql/client/view_module.rb', line 107

def const_path(name)
  pathname = ActiveSupport::Inflector.underscore(name.to_s)
  Dir[File.join(path, "{#{pathname},_#{pathname}}{/,.*}")].map { |fn| File.expand_path(fn) }.first
end

#eager_load!Object

Public: Eager load module and all subdependencies.

Use in production when cache_classes is true.

Traverses all app/views/*/.erb and loads all static constants defined in ERB files.

Examples

Views.eager_load!

Returns nothing.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/graphql/client/view_module.rb', line 34

def eager_load!
  return unless File.directory?(path)

  Dir.entries(path).each do |entry|
    next if entry == "." || entry == ".."
    name = entry.sub(/(\.\w+)+$/, "").camelize.to_sym
    if ViewModule.valid_constant_name?(name) && loadable_const_defined?(name)
      mod = const_get(name, false)
      mod.eager_load!
    end
  end

  nil
end

#load_module(path) ⇒ Object

Internal: Initialize new module for constant name and load ERB statics.

path - String path of directory or erb file.

Examples

load_module("app/views/users")
load_module("app/views/users/show.html.erb")

Returns new Module implementing Loadable concern.



122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/graphql/client/view_module.rb', line 122

def load_module(path)
  mod = Module.new

  if File.extname(path) == ".erb"
    contents = File.read(path)
    query, lineno = GraphQL::Client::Erubis.extract_graphql_section(contents)
    mod = client.parse(query, path, lineno) if query
  end

  mod.extend(ViewModule)
  mod.client = client
  mod.path = path
  mod
end

#loadable_const_defined?(name) ⇒ Boolean

Public: Override constant defined to check if constant name matches a view directory or template namespace.

name - String or Symbol constant name inherit - If the lookup will also search the ancestors (default: true)

Returns true if definition is found, otherwise false. def const_defined?(name, inherit = true)

if super(name.to_sym, inherit)
  true
elsif const_path(name)
  true
else
  false
end

end

Returns:

  • (Boolean)


81
82
83
84
85
86
87
88
89
# File 'lib/graphql/client/view_module.rb', line 81

def loadable_const_defined?(name)
  if const_defined?(name.to_sym, false)
    true
  elsif const_path(name)
    true
  else
    false
  end
end