Module: Releaf::Builders::FormBuilder::Associations

Included in:
Releaf::Builders::FormBuilder
Defined in:
app/builders/releaf/builders/form_builder/associations.rb

Instance Method Summary collapse

Instance Method Details

#association_reflector(reflection, fields) ⇒ Object


6
7
8
9
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 6

def association_reflector(reflection, fields)
  fields ||= resource_fields.association_attributes(reflection)
  Releaf::Builders::AssociationReflector.new(reflection, fields, sortable_column_name)
end

#field_type_add_nestedObject


156
157
158
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 156

def field_type_add_nested
  button(t('Add item'), "plus", class: "primary add-nested-item")
end

#field_type_remove_nestedObject


149
150
151
152
153
154
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 149

def field_type_remove_nested
  button_attributes = {title: t('Remove'), class: "danger remove-nested-item"}
  wrapper(class: "remove-item-box") do
    button(nil, "trash-o", button_attributes) << hidden_field("_destroy", class: "destroy")
  end
end

#reflect_on_association(association_name) ⇒ Object


11
12
13
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 11

def reflect_on_association(association_name)
  object.class.reflect_on_association(association_name)
end

#relation_name(name) ⇒ Object


2
3
4
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 2

def relation_name(name)
  name.to_s.sub(/_id$/, '').to_sym
end

#releaf_association_fields(reflection, fields) ⇒ Object


15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 15

def releaf_association_fields(reflection, fields)
  reflector = association_reflector(reflection, fields)

  case reflector.macro
  when :has_many
    releaf_has_many_association(reflector)
  when :belongs_to
    releaf_belongs_to_association(reflector)
  when :has_one
    releaf_has_one_association(reflector)
  else
    raise 'not implemented'
  end
end

#releaf_belongs_to_association(reflector) ⇒ Object


30
31
32
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 30

def releaf_belongs_to_association(reflector)
  releaf_has_one_or_belongs_to_association(reflector)
end

#releaf_has_many_association(reflector) ⇒ Object


48
49
50
51
52
53
54
55
56
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 48

def releaf_has_many_association(reflector)
  tag(:section, releaf_has_many_association_attributes(reflector)) do
    [
      releaf_has_many_association_header(reflector),
      releaf_has_many_association_body(reflector),
      releaf_has_many_association_footer(reflector)
    ]
  end
end

#releaf_has_many_association_attributes(reflector) ⇒ Object


58
59
60
61
62
63
64
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 58

def releaf_has_many_association_attributes reflector
  item_template = releaf_has_many_association_fields(reflector, reflector.klass.new, '_template_', true)
  {
    class: "nested",
    data: { name: reflector.name, "releaf-template" => html_escape(item_template.to_str) }
  }
end

#releaf_has_many_association_body(reflector) ⇒ Object


72
73
74
75
76
77
78
79
80
81
82
83
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 72

def releaf_has_many_association_body(reflector)
  attributes = {
    class: ["body", "list"]
  }
  attributes["data"] = {sortable: true} if reflector.sortable?

  tag(:div, attributes) do
    association_collection(reflector).each_with_index.map do |association_object, index|
      releaf_has_many_association_fields(reflector, association_object, index, reflector.destroyable?)
    end
  end
end

#releaf_has_many_association_field(reflector, destroyable) ⇒ Object


98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 98

def releaf_has_many_association_field(reflector, destroyable)
  content = ActiveSupport::SafeBuffer.new
  skippable_fields = []

  if reflector.sortable?
    skippable_fields << sortable_column_name
    content << hidden_field(sortable_column_name.to_sym, class: "item-position")
    content << tag(:div, "&nbsp;".html_safe, class: "handle")
  end

  content << releaf_fields(reflector.fields - skippable_fields)
  content << field_type_remove_nested if destroyable

  content
end

#releaf_has_many_association_fields(reflector, association_object, association_index, destroyable) ⇒ Object


89
90
91
92
93
94
95
96
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 89

def releaf_has_many_association_fields(reflector, association_object, association_index, destroyable)
  tag(:fieldset, class: ["item", "type-association"], data: {name: reflector.name, index: association_index}) do
    fields_for(reflector.name, association_object, relation_name: reflector.name,
               child_index: association_index, builder: self.class) do |builder|
      builder.releaf_has_many_association_field(reflector, destroyable)
    end
  end
end

85
86
87
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 85

def releaf_has_many_association_footer(_reflector)
  tag(:footer){ field_type_add_nested }
end

#releaf_has_many_association_header(reflector) ⇒ Object


66
67
68
69
70
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 66

def releaf_has_many_association_header(reflector)
  tag(:header) do
    tag(:h1, translate_attribute(reflector.name))
  end
end

#releaf_has_one_association(reflector) ⇒ Object


34
35
36
37
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 34

def releaf_has_one_association(reflector)
  object.send("build_#{reflector.name}") unless object.send(reflector.name).present?
  releaf_has_one_or_belongs_to_association(reflector)
end

#releaf_has_one_or_belongs_to_association(reflector) ⇒ Object


39
40
41
42
43
44
45
46
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 39

def releaf_has_one_or_belongs_to_association(reflector)
  tag(:fieldset, class: "type-association", data: {name: reflector.name}) do
    tag(:legend, translate_attribute(reflector.name)) <<
    fields_for(reflector.name, object.send(reflector.name), relation_name: reflector.name, builder: self.class) do |builder|
      builder.releaf_fields(reflector.fields)
    end
  end
end

#releaf_item_field(name, input: {}, label: {}, field: {}, options: {}, &block) ⇒ Object


126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 126

def releaf_item_field(name, input: {}, label: {}, field: {}, options: {}, &block)
  label_options = {translation_key: name.to_s.sub(/_id$/, '').to_s}
  attributes = input_attributes(name, {value: object.send(name)}.merge(input), options)
  options = {field: {type: "item"}, label: label_options}.deep_merge(options)


  # add empty value when validation exists, so user is forced to choose something
  unless options.key? :include_blank
    options[:include_blank] = true
    object.class.validators_on(name).each do |validator|
      next unless validator.is_a? ActiveModel::Validations::PresenceValidator
      # if new record, or object is missing (was deleted)
      options[:include_blank] = object.new_record? || object.send(relation_name(name)).blank?
      break
    end
  end


  choices = releaf_item_field_choices(name, options)
  content = select(name, choices, options, attributes)
  input_wrapper_with_label(name, content, label: label, field: field, options: options, &block)
end

#releaf_item_field_choices(name, options = {}) ⇒ Object


114
115
116
117
118
119
120
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 114

def releaf_item_field_choices(name, options = {})
  if options.key? :select_options
    options[:select_options]
  else
    releaf_item_field_collection(name, options).collect{|item| [resource_title(item), item.id]}
  end
end

#releaf_item_field_collection(name, options = {}) ⇒ Object


122
123
124
# File 'app/builders/releaf/builders/form_builder/associations.rb', line 122

def releaf_item_field_collection(name, options = {})
  options[:collection] || object.class.reflect_on_association(relation_name(name)).try(:klass).try(:all)
end