Module: Effective::Select2AjaxController

Extended by:
ActiveSupport::Concern
Included in:
AjaxController
Defined in:
app/controllers/concerns/effective/select2_ajax_controller.rb

Instance Method Summary collapse

Instance Method Details

#respond_with_select2_ajax(collection, skip_search: false, skip_authorize: false, skip_scope: false, &block) ⇒ Object



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
# File 'app/controllers/concerns/effective/select2_ajax_controller.rb', line 5

def respond_with_select2_ajax(collection, skip_search: false, skip_authorize: false, skip_scope: false, &block)
  raise('collection should be an ActiveRecord::Relation') unless collection.kind_of?(ActiveRecord::Relation)

  # Authorize
  EffectiveResources.authorize!(self, :index, collection.klass) unless skip_authorize

  # Scope
  if collection.respond_to?(:select2_ajax)
    collection = collection.select2_ajax
  elsif collection.respond_to?(:sorted)
    collection = collection.sorted
  end

  if (scope = params[:scope]).present? && !skip_scope
    raise("invalid scope #{scope}") unless Effective::Resource.new(collection.klass).scope?(scope)
    collection = collection.send(scope)
  end

  # Search
  if (term = params[:term]).present? && !skip_search
    columns = collection.klass.new.try(:to_select2_search_columns).presence
    collection = Effective::Resource.new(collection).search_any(term, columns: columns)
  end

  # Paginate
  per_page = 50
  page = (params[:page] || 1).to_i
  last = (collection.reselect(:id).count.to_f / per_page).ceil
  more = page < last

  offset = [(page - 1), 0].max * per_page
  collection = collection.limit(per_page).offset(offset)

  # Results
  results = collection.map do |resource|
    if block_given?
      option = yield(resource)
      raise('expected a Hash with id and text params') unless option.kind_of?(Hash) && option[:id] && option[:text]
      option
    else
      { id: resource.to_param, text: to_select2(resource) }
    end
  end

  # Respond
  respond_to do |format|
    format.js do
      render json: { results: results, pagination: { more: more } }
    end
  end
end