Module: Heimdallr::ResourceImplementation

Defined in:
lib/heimdallr/resource.rb

Class Method Summary collapse

Class Method Details

.action_type(action, options) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/heimdallr/resource.rb', line 123

def action_type(action, options)
  if options[:related]
    :related_record
  else
    action = action.to_sym
    case action
    when :index
      :collection
    when :new, :create
      :new_record
    when :show, :edit, :update, :destroy
      :record
    else
      if options[:collection] && options[:collection].include?(action)
        :collection
      elsif options[:new] && options[:new].include?(action)
        :new_record
      else
        :record
      end
    end
  end
end

.authorize(controller, options) ⇒ Object



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
# File 'lib/heimdallr/resource.rb', line 70

def authorize(controller, options)
  value = controller.instance_variable_get(ivar_name(controller, options))
  return unless value

  controller.instance_variable_set(ivar_name(controller, options.merge(:insecure => true)), value)

  value = value.restrict(controller.security_context)
  controller.instance_variable_set(ivar_name(controller, options), value)

  case controller.params[:action]
  when 'new', 'create'
    value.assign_attributes(value.reflect_on_security[:restrictions].fixtures[:create])

    unless value.reflect_on_security[:operations].include? :create
      raise Heimdallr::AccessDenied, "Cannot create model"
    end

  when 'edit', 'update'
    value.assign_attributes(value.reflect_on_security[:restrictions].fixtures[:update])

    unless value.reflect_on_security[:operations].include? :update
      raise Heimdallr::AccessDenied, "Cannot update model"
    end

  when 'destroy'
    unless value.destroyable?
      raise Heimdallr::AccessDenied, "Cannot delete model"
    end
  end unless options[:related]
end

.class_name(options) ⇒ Object



155
156
157
158
159
160
161
# File 'lib/heimdallr/resource.rb', line 155

def class_name(options)
  if options.kind_of? Hash
    options[:resource]
  else
    options.to_s
  end.classify
end

.ivar_name(controller, options) ⇒ Object



115
116
117
118
119
120
121
# File 'lib/heimdallr/resource.rb', line 115

def ivar_name(controller, options)
  if action_type(controller.params[:action], options) == :collection
    :"@#{variable_name(options).pluralize}"
  else
    :"@#{variable_name(options)}"
  end
end

.load(controller, options) ⇒ Object



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
# File 'lib/heimdallr/resource.rb', line 17

def load(controller, options)
  unless controller.instance_variable_defined?(ivar_name(controller, options))
    if options.has_key? :through
      target = load_target(controller, options)

      if target
        if options[:singleton]
          scope = target.send(:"#{variable_name(options)}")
        else
          scope = target.send(:"#{variable_name(options).pluralize}")
        end
      elsif options[:shallow]
        scope = class_name(options).constantize.scoped
      else
        raise "Cannot fetch #{options[:resource]} via #{options[:through]}"
      end
    else
      scope = class_name(options).constantize.scoped
    end

    loaders = {
      collection: -> {
        controller.instance_variable_set(ivar_name(controller, options), scope)
      },

      new_record: -> {
        controller.instance_variable_set(
          ivar_name(controller, options),
          scope.new(controller.params[params_key_name(options)] || {})
        )
      },

      record: -> {
        controller.instance_variable_set(
          ivar_name(controller, options),
          scope.find([:"#{params_key_name(options)}_id", :id].map{|key| controller.params[key] }.reject(&:blank?)[0])
        )
      },

      related_record: -> {
        unless controller.params[:"#{params_key_name(options)}_id"].blank?
          controller.instance_variable_set(
            ivar_name(controller, options),
            scope.find(controller.params[:"#{params_key_name(options)}_id"])
          )
        end
      }
    }

    loaders[action_type(controller.params[:action], options)].()
  end
end

.load_target(controller, options) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/heimdallr/resource.rb', line 101

def load_target(controller, options)
  Array.wrap(options[:through]).map do |parent|
    loaded = controller.instance_variable_get(:"@#{variable_name parent}")
    unless loaded
      load(controller, :resource => parent.to_s, :related => true)
      loaded = controller.instance_variable_get(:"@#{variable_name parent}")
    end
    if loaded && options[:authorize_chain]
      authorize(controller, :resource => parent.to_s, :related => true)
    end
    controller.instance_variable_get(:"@#{variable_name parent}")
  end.reject(&:nil?).first
end

.params_key_name(options) ⇒ Object



163
164
165
166
167
168
169
# File 'lib/heimdallr/resource.rb', line 163

def params_key_name(options)
  if options.kind_of? Hash
    options[:resource]
  else
    options.to_s
  end.split('/').last
end

.prepare_options(klass, options) ⇒ Object



7
8
9
10
11
12
13
14
15
# File 'lib/heimdallr/resource.rb', line 7

def prepare_options(klass, options)
  options = options.merge :resource => (options[:resource] || klass.name.sub(/Controller$/, '').underscore).to_s

  filter_options = {}
  filter_options[:only]   = options.delete(:only)   if options.has_key?(:only)
  filter_options[:except] = options.delete(:except) if options.has_key?(:except)

  [ options, filter_options ]
end

.variable_name(options) ⇒ Object



147
148
149
150
151
152
153
# File 'lib/heimdallr/resource.rb', line 147

def variable_name(options)
  if options.kind_of? Hash
    options[:resource]
  else
    options.to_s
  end.parameterize('_')
end