Module: ActiveScaffold::Helpers::AssociationHelpers

Included in:
ViewHelpers
Defined in:
lib/active_scaffold/helpers/association_helpers.rb

Instance Method Summary collapse

Instance Method Details

#association_klass_scoped(association, klass, record) ⇒ Object

[View source]

54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/active_scaffold/helpers/association_helpers.rb', line 54

def association_klass_scoped(association, klass, record)
  if nested? && nested.through_association? && nested.child_association&.through_reflection == association
    # only ActiveRecord associations
    if nested.association.through_reflection.collection?
      nested_parent_record.send(nested.association.through_reflection.name)
    else
      klass.where(association.association_primary_key => nested_parent_record.send(nested.association.through_reflection.name)&.id)
    end
  else
    klass
  end
end

#association_options_count(association, conditions = nil) ⇒ Object

[View source]

78
79
80
# File 'lib/active_scaffold/helpers/association_helpers.rb', line 78

def association_options_count(association, conditions = nil)
  association.klass.where(conditions).count
end

#association_options_find(association, conditions = nil, klass = nil, record = nil) ⇒ Object

Provides a way to honor the :conditions on an association while searching the association's klass

[View source]

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
# File 'lib/active_scaffold/helpers/association_helpers.rb', line 16

def association_options_find(association, conditions = nil, klass = nil, record = nil)
  if klass.nil? && association.polymorphic?
    class_name = record.send(association.foreign_type) if association.belongs_to?
    return [] if class_name.blank?
    klass = class_name.constantize
    cache = !block_given?
  else
    cache = !block_given? && klass.nil?
    klass ||= association.klass
  end

  conditions ||= options_for_association_conditions(association, record)
  cache_association_options(association, conditions, klass, cache) do
    klass = association_klass_scoped(association, klass, record)
    relation = klass.where(conditions)
    column = column_for_association(association, record)
    if column&.includes
      include_assoc = column.includes.find { |assoc| assoc.is_a?(Hash) && assoc.include?(association.name) }
      relation = relation.includes(include_assoc[association.name]) if include_assoc
    end
    if column&.sort && column.sort&.dig(:sql)
      # with threasafe enabled, column.sort[:sql] returns proxied strings and
      # regexp capture won't work, which rails uses internally, so to_s is needed
      relation = relation.order(Array(column.sort[:sql]).map(&:to_s))
    end
    relation = yield(relation) if block_given?
    relation.to_a
  end
end

#cache_association_options(association, conditions, klass, cache = true) ⇒ Object

Cache the options for select

[View source]

5
6
7
8
9
10
11
12
13
# File 'lib/active_scaffold/helpers/association_helpers.rb', line 5

def cache_association_options(association, conditions, klass, cache = true)
  if active_scaffold_config.cache_association_options && cache
    @_associations_cache ||= Hash.new { |h, k| h[k] = {} }
    key = [association.name, association.inverse_klass.name, klass.name].join('/')
    @_associations_cache[key][conditions] ||= yield
  else
    yield
  end
end

#column_for_association(association, record) ⇒ Object

[View source]

46
47
48
49
50
51
52
# File 'lib/active_scaffold/helpers/association_helpers.rb', line 46

def column_for_association(association, record)
  active_scaffold_config_for(record.class).columns[association.name]
rescue StandardError => e
  message = "Error on config for #{record.class.name}:"
  Rails.logger.warn "#{message}\n#{e.message}\n#{e.backtrace.join("\n")}"
  nil
end

#options_for_association_conditions(association, record = nil) ⇒ Object

A useful override for customizing the records present in an association dropdown. Should work in both the subform and form_ui=>:select modes. Check association.name to specialize the conditions per-column.

[View source]

90
91
92
93
94
95
# File 'lib/active_scaffold/helpers/association_helpers.rb', line 90

def options_for_association_conditions(association, record = nil)
  return nil if association.through?
  return nil unless association.has_one? || association.has_many?
  # Find only orphaned objects
  {association.foreign_key => nil}
end

#options_for_association_count(association, record) ⇒ Object

[View source]

82
83
84
85
# File 'lib/active_scaffold/helpers/association_helpers.rb', line 82

def options_for_association_count(association, record)
  conditions = options_for_association_conditions(association, record)
  association_options_count(association, conditions)
end

#record_select_params_for_add_existing(association, edit_associated_url_options, record) ⇒ Object

[View source]

97
98
99
# File 'lib/active_scaffold/helpers/association_helpers.rb', line 97

def record_select_params_for_add_existing(association, edit_associated_url_options, record)
  {:onselect => "ActiveScaffold.record_select_onselect(#{url_for(edit_associated_url_options).to_json}, #{active_scaffold_id.to_json}, id);"}
end

#sorted_association_options_find(association, conditions = nil, record = nil) ⇒ Object

Sorts the options for select

[View source]

68
69
70
71
72
73
74
75
76
# File 'lib/active_scaffold/helpers/association_helpers.rb', line 68

def sorted_association_options_find(association, conditions = nil, record = nil)
  options = association_options_find(association, conditions, nil, record)
  column = column_for_association(association, record)
  unless column&.sort && column.sort&.dig(:sql)
    method = column.options[:label_method] if column
    options = options.sort_by(&(method || :to_label).to_sym)
  end
  options
end