File: gon.rb

package info (click to toggle)
ruby-gon 6.4.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 504 kB
  • sloc: ruby: 1,383; makefile: 9
file content (132 lines) | stat: -rw-r--r-- 3,049 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
require 'request_store'
require 'action_view'
require 'action_controller'
require 'multi_json'

require 'gon/base'
require 'gon/env_finder'
require 'gon/global'
require 'gon/watch'
require 'gon/request'
require 'gon/helpers'
require 'gon/escaper'
require 'gon/rabl'
require 'gon/jbuilder'
require 'gon/jbuilder/parser'
require 'gon/json_dumper'

# NOTE : ActionDispatch::Request#uuid appears only in Rails 3.2.1
unless ActionDispatch::Request.public_instance_methods.include?(:uuid)
  require 'gon/compatibility/old_rails'
end

require 'gon/spec_helpers'

class Gon
  class << self

    def global
      Gon::Global
    end

    def watch
      Gon::Watch
    end

    def method_missing(method, *args, &block)
      if method.to_s =~ /=$/
        if public_method_name?(method)
          raise "You can't use Gon public methods for storing data: #{method}"
        end
        if self == Gon && !current_gon
          raise 'Assign request-specific gon variables only through `gon` helper, not through Gon constant'
        end

        set_variable(method.to_s.delete('='), args[0])
      else
        get_variable(method.to_s)
      end
    end

    def get_variable(name)
      current_gon.gon[name]
    end

    def set_variable(name, value)
      current_gon.gon[name] = value
    end

    def merge_variable(name, value)
      old_value = all_variables[name]
      if value.is_a?(Hash) && old_value.is_a?(Hash)
        value = old_value.deep_merge(value)
      end
      set_variable(name, value)
    end

    def push(data = {}, merge = false)
      raise 'Object must have each_pair method' unless data.respond_to? :each_pair

      if merge
        data.each_pair do |name, value|
          merge_variable(name.to_s, value)
        end
      else
        data.each_pair do |name, value|
          set_variable(name.to_s, value)
        end
      end
    end

    def all_variables
      current_gon ? current_gon.gon : {}
    end

    def clear
      current_gon.clear if current_gon
    end

    def rabl(*args)
      data, options = Gon::Rabl.handler(args)
      store_builder_data 'rabl', data, options
    end

    def jbuilder(*args)
      ensure_template_handler_is_defined
      data, options = Gon::Jbuilder.handler(args)
      store_builder_data 'jbuilder', data, options
    end

    def inspect
      'Gon'
    end

    private

    def current_gon
      RequestStore.store[:gon]
    end

    def store_builder_data(builder, data, options)
      if options[:as]
        set_variable(options[:as].to_s, data)
      elsif data.is_a? Hash
        data.each { |k, v| set_variable(k, v) }
      else
        set_variable(builder, data)
      end
    end

    def public_method_name?(method)
      public_methods.include?(method.to_s[0..-2].to_sym)
    end

    # JbuilderTemplate will not be defined if jbuilder is required
    # before gon. By loading jbuilder again, JbuilderTemplate will
    # now be defined
    def ensure_template_handler_is_defined
      load 'jbuilder.rb' unless defined?(JbuilderTemplate)
    end

  end
end