Module: Kojac::ControllerOpMethods

Defined in:
lib/kojac/kojac_rails.rb

Class Method Summary collapse

Class Method Details

.add_opObject

def execute_op puts ‘execute_op’ end



364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
# File 'lib/kojac/kojac_rails.rb', line 364

def add_op
  ring = current_user.try(:ring)
  op = params[:op]
  model = deduce_model_class
  raise "ADD only supports associated collections at present eg order.items" unless op[:key].index('.')

  item = KojacUtils.model_for_key(op[:key].base_key)
  assoc = (assoc=op[:key].key_assoc) && assoc.to_sym
  id = op[:value]['id']

  ma = item.class.reflect_on_association(assoc)
  case ma.macro
    when :has_many
      assoc_class = ma.klass
      assoc_item = assoc_class.find(id)
      item.send(assoc) << assoc_item

      #ids_method = assoc.to_s.singularize+'_ids'
      #ids = item.send(ids_method.to_sym)
      #item.send((ids_method+'=').to_sym,ids + [id])
      result_key = assoc_item.kojac_key
      merge_model_into_results(assoc_item)
    else
      raise "ADD does not yet support #{ma.macro} associations"
  end
  {
    key: op[:key],
    verb: op[:verb],
    result_key: result_key,
    results: results
  }
end

.create_on_association(aItem, aAssoc, aValues, aRing) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/kojac/kojac_rails.rb', line 128

def create_on_association(aItem,aAssoc,aValues,aRing)
  raise "User does not have permission for create on #{aAssoc}" unless aItem.class.permitted_associations(:create,aRing).include?(aAssoc.to_sym)

  return nil unless ma = aItem.class.reflect_on_association(aAssoc.to_sym)
  a_model_class = ma.klass

  aValues = KojacUtils.upgrade_hashes_to_params(aValues || {})

  case ma.macro
    when :belongs_to
      return nil if !aValues.is_a?(Hash)
      fields = aValues.permit( *a_model_class.permitted_fields(:write,aRing) )
      return aItem.send("build_#{aAssoc}".to_sym,fields)
    when :has_many
      aValues = [aValues] if aValues.is_a?(Hash)
      return nil unless aValues.is_a? Array
      aValues.each do |v|
        fields = v.permit( *a_model_class.permitted_fields(:write,aRing) )
        new_sub_item = nil
        case ma.macro
          when :has_many
            new_sub_item = aItem.send(aAssoc.to_sym).create(fields)
          else
            raise "#{ma.macro} association unsupported in CREATE"
        end
        merge_model_into_results(new_sub_item)
      end
  end
  #
  #
  #
  #a_value = op[:value][a]        # get data for this association, assume {}
  #if a_value.is_a?(Hash)
  #  a_model_class = ma.klass
  #  fields = a_value.permit( *permitted_fields(:write,a_model_class) )
  #  item.send("build_#{a}".to_sym,fields)
  #  included_assocs << a.to_sym
  #elsif a_value.is_a?(Array)
  #  raise "association collections not yet implemented for create"
  #else
  #  next
  #end
end

.create_opObject



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/kojac/kojac_rails.rb', line 172

def create_op
  ring = current_user.try(:ring)
  op = params[:op]
  options = op[:options] || {}
  model_class = deduce_model_class
  resource,id,assoc = op['key'].split_kojac_key
  if assoc  # create operation on an association eg. {verb: "CREATE", key: "order.items"}
    raise "User does not have permission for #{op[:verb]} operation on #{model_class.to_s}.#{assoc}" unless model_class.permitted_associations(:create,ring).include?(assoc.to_sym)
    item = KojacUtils.model_for_key(key_join(resource,id))
    ma = model_class.reflect_on_association(assoc.to_sym)
    a_value = op[:value]        # get data for this association, assume {}
    raise "create multiple not yet implemented for associations" unless a_value.is_a?(Hash)

    a_model_class = ma.klass
    p_fields = a_model_class.permitted_fields(:write,ring)
    fields = a_value.permit( *p_fields )
    new_sub_item = nil
    case ma.macro
      when :has_many
        new_sub_item = item.send(assoc.to_sym).create(fields)
      else
        raise "#{ma.macro} association unsupported in CREATE"
    end
    result_key = op[:result_key] || new_sub_item.kojac_key
    merge_model_into_results(new_sub_item)
  else    # create operation on a resource eg. {verb: "CREATE", key: "order_items"} but may have embedded association values
    p_fields = model_class.permitted_fields(:write,ring)
    raise "User does not have permission for #{op[:verb]} operation on #{model_class.to_s}" unless model_class.ring_can?(:create,ring)

    p_fields = op[:value].permit( *p_fields )
    item = model_class.create!(p_fields)

    options_include = options['include'] || []
    included_assocs = []
    p_assocs = model_class.permitted_associations(:write,ring)
    if p_assocs
      p_assocs.each do |a|
        next unless (a_value = op[:value][a]) || options_include.include?(a.to_s)
        create_on_association(item,a,a_value,ring)
        included_assocs << a.to_sym
      end
    end
    item.save!
    result_key = op[:result_key] || item.kojac_key
    merge_model_into_results(item,result_key,:include => included_assocs)
  end
  {
    key: op[:key],
    verb: op[:verb],
    result_key: result_key,
    results: results
  }
end

.deduce_model_classObject



120
121
122
# File 'lib/kojac/kojac_rails.rb', line 120

def deduce_model_class
  KojacUtils.model_class_for_key(self.kojac_resource)
end

.destroy_opObject



345
346
347
348
349
350
351
352
353
354
355
356
357
358
# File 'lib/kojac/kojac_rails.rb', line 345

def destroy_op
  ring = current_user.try(:ring)
  op = params[:op]
  result_key = op[:result_key] || op[:key]
  item = KojacUtils.model_for_key(op[:key])
  item.destroy if item
  results[result_key] = nil
  {
    key: op[:key],
    verb: op[:verb],
    result_key: result_key,
    results: results
  }
end

.included(aClass) ⇒ Object



101
102
103
104
105
# File 'lib/kojac/kojac_rails.rb', line 101

def self.included(aClass)
  #aClass.send :extend, ClassMethods
  aClass.send :include, ActiveSupport::Callbacks
  aClass.send :define_callbacks, :update_op, :scope => [:kind, :name]
end

.kojac_resourceObject



124
125
126
# File 'lib/kojac/kojac_rails.rb', line 124

def kojac_resource
  self.class.to_s.chomp('Controller').snake_case
end

.read_opObject



263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# File 'lib/kojac/kojac_rails.rb', line 263

def read_op
  op = params[:op]
  key = op[:key]
  result_key = nil
  resource,id = key.split '__'
  model = deduce_model_class

  if id   # item
    if model
      item = model.by_key(key,op)
      result_key = op[:result_key] || (item && item.kojac_key) || op[:key]
      merge_model_into_results(item,result_key,op[:options])
    else
      result_key = op[:result_key] || op[:key]
      results[result_key] = null
    end
  else    # collection
    result_key = op[:result_key] || op[:key]
    results[result_key] = []
    if model
      items = model.by_key(key,op)
      items.each do |m|
        item_key = m.kojac_key
        results[result_key] << item_key.bite(resource+'__')
        merge_model_into_results(m,item_key,op[:options])
      end
    end
  end
  {
    key: op[:key],
    verb: op[:verb],
    results: results,
    result_key: result_key
  }
end

.remove_opObject



397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
# File 'lib/kojac/kojac_rails.rb', line 397

def remove_op
  ring = current_user.try(:ring)
  op = params[:op]
  model = deduce_model_class
  raise "REMOVE only supports associated collections at present eg order.items" unless op[:key].key_assoc

  item = KojacUtils.model_for_key(op[:key].base_key)
  assoc = (assoc=op[:key].key_assoc) && assoc.to_sym
  id = op[:value]['id']

  ma = item.class.reflect_on_association(assoc)
  case ma.macro
    when :has_many
      assoc_class = ma.klass
      if assoc_item = item.send(assoc).find(id)
        item.send(assoc).delete(assoc_item)
        result_key = assoc_item.kojac_key
        if (assoc_item.destroyed?)
          results[result_key] = nil
        else
          merge_model_into_results(assoc_item,result_key)
        end
      end
    else
      raise "REMOVE does not yet support #{ma.macro} associations"
  end
  {
    key: op[:key],
    verb: op[:verb],
    result_key: result_key,
    results: results
  }
end

.resultsObject



116
117
118
# File 'lib/kojac/kojac_rails.rb', line 116

def results
  @results ||= {}
end

.update_opObject



299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
# File 'lib/kojac/kojac_rails.rb', line 299

def update_op
  result = nil
  model = deduce_model_class

  ring = current_user.try(:ring)
  op = params[:op]
  result_key = nil
  if self.item = model.by_key(op[:key],op)

    run_callbacks :update_op do
      item.update_permitted_attributes!(op[:value], ring)

      associations = model.permitted_associations(:write,ring)
      associations.each do |k|
        next unless assoc = model.reflect_on_association(k)
        next unless op[:value][k]
        case assoc.macro
          when :belongs_to
            if leaf = (item.send(k) || item.send("build_#{k}".to_sym))
              #permitted_fields = leaf.class.permitted_fields(:write,ring)
              #permitted_fields = op[:value][k].permit( *permitted_fields )
              #leaf.assign_attributes(permitted_fields, :without_protection => true)
              #leaf.save!
              leaf.update_permitted_attributes!(op[:value][k], ring)
            end
        end
      end

      result_key = item.kojac_key
      results[result_key] = item

      associations.each do |a|
        next unless assoc_item = item.send(a)
        next unless key = assoc_item.respond_to?(:kojac_key) && assoc_item.kojac_key
        results[key] = assoc_item
      end
    end
  end
  {
    key: op[:key],
    verb: op[:verb],
    result_key: result_key,
    results: results
  }
end