binda 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +83 -25
  3. data/app/assets/javascripts/binda/application.js +3 -3
  4. data/app/assets/javascripts/binda/components/bootstrap.js +3 -4
  5. data/app/assets/javascripts/binda/components/field_group_editor.js +10 -10
  6. data/app/assets/javascripts/binda/components/field_setting_choices.js +61 -49
  7. data/app/assets/javascripts/binda/components/fileupload.js +135 -118
  8. data/app/assets/javascripts/binda/components/form_item.js +65 -65
  9. data/app/assets/javascripts/binda/components/form_item_editor.js +19 -19
  10. data/app/assets/javascripts/binda/components/form_item_image.js +11 -13
  11. data/app/assets/javascripts/binda/components/form_item_repeater.js +77 -71
  12. data/app/assets/javascripts/binda/components/login-shader.js +171 -164
  13. data/app/assets/javascripts/binda/components/login_form.js +65 -73
  14. data/app/assets/javascripts/binda/components/radio-toggle.js +8 -12
  15. data/app/assets/javascripts/binda/components/select2.js +19 -14
  16. data/app/assets/javascripts/binda/components/sortable.js +76 -71
  17. data/app/assets/javascripts/binda/dist/binda.bundle.js +735 -727
  18. data/app/assets/javascripts/binda/index.js +49 -35
  19. data/app/assets/stylesheets/binda/components/assets_manager.scss +13 -22
  20. data/app/assets/stylesheets/binda/components/b-alert.scss +18 -14
  21. data/app/assets/stylesheets/binda/components/b-btn.scss +24 -43
  22. data/app/assets/stylesheets/binda/components/field_setting_choices.scss +16 -31
  23. data/app/assets/stylesheets/binda/components/fileupload.scss +25 -42
  24. data/app/assets/stylesheets/binda/components/form_item.scss +51 -93
  25. data/app/assets/stylesheets/binda/components/form_item_choices.scss +7 -10
  26. data/app/assets/stylesheets/binda/components/login.scss +2 -2
  27. data/app/assets/stylesheets/binda/components/main_header.scss +5 -10
  28. data/app/assets/stylesheets/binda/components/main_sidebar.scss +42 -46
  29. data/app/assets/stylesheets/binda/components/main_sortable_table.scss +12 -21
  30. data/app/assets/stylesheets/binda/components/main_table.scss +18 -35
  31. data/app/assets/stylesheets/binda/components/popup_warning.scss +14 -27
  32. data/app/assets/stylesheets/binda/components/select2.scss +46 -48
  33. data/app/assets/stylesheets/binda/components/sortable.scss +25 -45
  34. data/app/assets/stylesheets/binda/components/standard-form.scss +43 -73
  35. data/app/assets/stylesheets/binda/controllers/users_sessions_new.scss +52 -89
  36. data/app/assets/stylesheets/binda/index.scss +0 -1
  37. data/app/assets/stylesheets/binda/settings/buttons.scss +9 -10
  38. data/app/assets/stylesheets/binda/settings/common.scss +17 -22
  39. data/app/assets/stylesheets/binda/settings/fonts.scss +112 -67
  40. data/app/assets/stylesheets/binda/settings/tiny_mce_overrides.scss +20 -36
  41. data/app/assets/stylesheets/binda/settings/variables.scss +38 -43
  42. data/app/controllers/binda/choices_controller.rb +14 -11
  43. data/app/controllers/binda/components_controller.rb +6 -4
  44. data/app/controllers/binda/structures_controller.rb +7 -3
  45. data/app/helpers/binda/components_helper.rb +69 -3
  46. data/app/helpers/binda/field_groups_helper.rb +16 -6
  47. data/app/helpers/binda/structures_helper.rb +1 -4
  48. data/app/models/binda/application_record.rb +4 -1
  49. data/app/models/binda/asset.rb +3 -1
  50. data/app/models/binda/b.rb +1 -0
  51. data/app/models/binda/category.rb +1 -0
  52. data/app/models/binda/checkbox.rb +2 -0
  53. data/app/models/binda/choice.rb +74 -41
  54. data/app/models/binda/component.rb +1 -1
  55. data/app/models/binda/date.rb +4 -0
  56. data/app/models/binda/deprecation.rb +7 -0
  57. data/app/models/binda/field_group.rb +16 -3
  58. data/app/models/binda/field_setting.rb +168 -41
  59. data/app/models/binda/image.rb +1 -0
  60. data/app/models/binda/radio.rb +2 -0
  61. data/app/models/binda/relation.rb +3 -0
  62. data/app/models/binda/repeater.rb +3 -0
  63. data/app/models/binda/selection.rb +237 -0
  64. data/app/models/binda/string.rb +4 -0
  65. data/app/models/binda/structure.rb +25 -14
  66. data/app/models/binda/text.rb +9 -0
  67. data/app/models/binda/video.rb +1 -0
  68. data/app/models/concerns/binda/default_helpers.rb +40 -31
  69. data/app/models/concerns/binda/deprecations.rb +6 -0
  70. data/app/models/concerns/binda/fieldable_association_helpers.rb +366 -0
  71. data/app/models/concerns/binda/fieldable_associations.rb +32 -369
  72. data/app/views/binda/boards/edit.html.erb +15 -2
  73. data/app/views/binda/categories/_form.html.erb +24 -51
  74. data/app/views/binda/categories/edit.html.erb +23 -3
  75. data/app/views/binda/categories/index.html.erb +49 -25
  76. data/app/views/binda/categories/new.html.erb +21 -2
  77. data/app/views/binda/components/edit.html.erb +27 -4
  78. data/app/views/binda/components/index.html.erb +47 -50
  79. data/app/views/binda/components/new.html.erb +12 -2
  80. data/app/views/binda/components/sort_index.html.erb +28 -13
  81. data/app/views/binda/field_groups/_form_body.html.erb +43 -82
  82. data/app/views/binda/field_groups/_form_item.html.erb +3 -120
  83. data/app/views/binda/field_groups/_form_section.html.erb +11 -16
  84. data/app/views/binda/field_groups/_form_section_repeater.html.erb +7 -15
  85. data/app/views/binda/field_groups/edit.html.erb +14 -2
  86. data/app/views/binda/field_groups/form_item/_form_item_choice_editor.html.erb +11 -0
  87. data/app/views/binda/field_groups/form_item/_form_item_editor.html.erb +14 -0
  88. data/app/views/binda/field_groups/form_item/_form_item_header.html.erb +25 -0
  89. data/app/views/binda/field_groups/form_item/_form_item_new_editor.html.erb +8 -0
  90. data/app/views/binda/field_groups/form_item/_form_item_persisted_editor.html.erb +27 -0
  91. data/app/views/binda/field_groups/form_item/form_item_choice/_form_item_allow_null_choice.html.erb +11 -0
  92. data/app/views/binda/field_groups/form_item/form_item_choice/_form_item_choice_header.html.erb +11 -0
  93. data/app/views/binda/field_groups/form_item/form_item_choice/_form_item_default_choice.html.erb +11 -0
  94. data/app/views/binda/field_groups/form_item/form_item_choice/_form_item_new_choice.html.erb +16 -0
  95. data/app/views/binda/field_groups/form_item/form_item_choice/_form_item_persisted_choices.html.erb +16 -0
  96. data/app/views/binda/field_groups/new.html.erb +14 -2
  97. data/app/views/binda/field_settings/_form_body.html.erb +1 -3
  98. data/app/views/binda/field_settings/edit.html.erb +1 -1
  99. data/app/views/binda/field_settings/new.html.erb +1 -1
  100. data/app/views/binda/fieldable/_form_body.html.erb +24 -72
  101. data/app/views/binda/fieldable/_form_item_date.html.erb +1 -4
  102. data/app/views/binda/fieldable/_form_item_image.html.erb +3 -7
  103. data/app/views/binda/fieldable/_form_item_new_repeater.html.erb +0 -13
  104. data/app/views/binda/fieldable/_form_item_selections.html.erb +20 -112
  105. data/app/views/binda/fieldable/form_item_selections/_form_item_checkbox.html.erb +34 -0
  106. data/app/views/binda/fieldable/form_item_selections/_form_item_radio.html.erb +28 -0
  107. data/app/views/binda/fieldable/form_item_selections/_form_item_selection.html.erb +30 -0
  108. data/app/views/binda/manage/users/_form_body.html.erb +1 -31
  109. data/app/views/binda/manage/users/edit.html.erb +12 -2
  110. data/app/views/binda/manage/users/index.html.erb +36 -19
  111. data/app/views/binda/manage/users/new.html.erb +14 -3
  112. data/app/views/binda/structures/_form_body.html.erb +2 -25
  113. data/app/views/binda/structures/_form_section.html.erb +43 -65
  114. data/app/views/binda/structures/_form_sidebar.html.erb +19 -12
  115. data/app/views/binda/structures/edit.html.erb +20 -3
  116. data/app/views/binda/structures/index.html.erb +46 -26
  117. data/app/views/binda/structures/new.html.erb +13 -2
  118. data/app/views/binda/structures/sort_index.html.erb +37 -17
  119. data/app/views/binda/users/sessions/new.html.erb +25 -20
  120. data/app/views/layouts/binda/_form_errors.html.erb +10 -0
  121. data/app/views/layouts/binda/_sidebar.html.erb +6 -6
  122. data/app/views/layouts/binda/application.html.erb +1 -1
  123. data/config/initializers/carrierwave.rb +3 -2
  124. data/config/locales/en.yml +56 -12
  125. data/config/tinymce.yml +2 -2
  126. data/db/migrate/1_create_binda_tables.rb +1 -1
  127. data/lib/binda/version.rb +1 -1
  128. data/lib/generators/binda/setup/setup_generator.rb +2 -2
  129. data/lib/tasks/add_default_choice_to_all_selections_with_no_choices_task.rake +6 -0
  130. metadata +58 -8
  131. data/app/assets/stylesheets/binda/components/form_item_image.scss +0 -0
  132. data/app/views/binda/field_groups/_form_item_choice.erb +0 -104
@@ -1,14 +1,17 @@
1
1
  module Binda
2
2
  # Fieldable associations are Binda's core feature.
3
3
  #
4
- # They provide model classes with a collection of fields (texts, assets, dates and so on)
5
- # to store data in a simple yet powerful way. It's possible to make use of a set of helpers to
6
- # retrieve fields data belonging to each model instance. See the following methods.
4
+ # They provide model classes like `Binda::Component` and `Binda::Board` with a collection of fields
5
+ # (texts, assets, dates and so on) to store data in a simple yet powerful way. It's possible to
6
+ # make use of a set of helpers to retrieve fields data belonging to each model instance.
7
7
  module FieldableAssociations
8
8
 
9
9
  extend ActiveSupport::Concern
10
10
 
11
11
  included do
12
+
13
+ include FieldableAssociationHelpers
14
+
12
15
  # Fieldable Associations
13
16
  #
14
17
  # If you add a new field remember to update:
@@ -82,355 +85,6 @@ module Binda
82
85
  # end
83
86
  # end
84
87
  # end
85
-
86
- end
87
-
88
- # Get the object related to that field setting
89
- # If the object doesn't exists yet it will return nil
90
- #
91
- # @param field_slug [string] The slug of the field setting
92
- # @return [string] Returns the content of the text
93
- # @return [error] Raise an error if no record is found
94
- def get_text field_slug
95
- obj = self.texts.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) && t.type != 'Binda::String' }
96
- unless obj.nil?
97
- obj.content
98
- else
99
- check_text_error field_slug
100
- end
101
- end
102
-
103
- # Check why get_text doesn't return a value
104
- # This method isn't supposed to be used by anything other than get_text method
105
- def check_text_error field_slug
106
- you_mean_string = !self.strings.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) && t.type = 'Binda::String' }.nil?
107
- if you_mean_string
108
- raise ArgumentError, "This slug (#{field_slug}) is associated to a string not a text. Use get_string() instead on instance (#{self.class.name} ##{self.id}).", caller
109
- else
110
- raise ArgumentError, "There isn't any text associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller
111
- end
112
- end
113
-
114
- # Get the object related to that field setting
115
- #
116
- # @param field_slug [string] The slug of the field setting
117
- # @return [boolean]
118
- def has_text field_slug
119
- obj = self.texts.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) && t.type != 'Binda::String' }
120
- raise ArgumentError, "There isn't any text associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
121
- if obj.present?
122
- return !obj.content.blank?
123
- else
124
- return false
125
- end
126
- end
127
-
128
- # Get the object related to that field setting
129
- # If the object doesn't exists yet it will return nil
130
- #
131
- # @param field_slug [string] The slug of the field setting
132
- # @return [string] Returns the content of the string
133
- # @return [error] Raise an error if no record is found
134
- def get_string field_slug
135
- obj = self.strings.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) && t.type == 'Binda::String' }
136
- unless obj.nil?
137
- obj.content
138
- else
139
- check_string_error field_slug
140
- end
141
- end
142
-
143
- # Check why get_string doesn't return a value
144
- # This method isn't supposed to be used by anything other than get_string method
145
- def check_string_error field_slug
146
- you_mean_text = !self.strings.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) && t.type = 'Binda::Text' }.nil?
147
- if you_mean_text
148
- raise ArgumentError, "This slug (#{field_slug}) is associated to a text not a string. Use get_text() instead on instance (#{self.class.name} ##{self.id}).", caller
149
- else
150
- raise ArgumentError, "There isn't any string associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller
151
- end
152
- end
153
-
154
- # Get the object related to that field setting
155
- #
156
- # @param field_slug [string] The slug of the field setting
157
- # @return [boolean]
158
- def has_string field_slug
159
- obj = self.strings.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) && t.type == 'Binda::String' }
160
- raise ArgumentError, "There isn't any string associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
161
- if obj.present?
162
- return !obj.content.blank?
163
- else
164
- return false
165
- end
166
- end
167
-
168
- # Check if the field has an attached image
169
- #
170
- # @param field_slug [string] The slug of the field setting
171
- # @return [boolean]
172
- def has_image field_slug
173
- obj = self.images.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) }
174
- # Alternative query
175
- # obj = Image.where(field_setting_id: FieldSetting.get_id( field_slug ), fieldable_id: self.id, fieldable_type: self.class.to_s ).first
176
- raise ArgumentError, "There isn't any image associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
177
- return obj.image.present?
178
- end
179
-
180
- # Get the image url based on the size provided,
181
- # default is Carrierwave default (usually the real size)
182
- #
183
- # @param field_slug [string] The slug of the field setting
184
- # @param size [string] The size. It can be 'thumb' 200x200 cropped,
185
- # 'medium' 700x700 max size, 'large' 1400x1400 max size, or blank
186
- # @return [string] The url of the image
187
- def get_image_url field_slug, size = ''
188
- get_image_info( field_slug, size, 'url' )
189
- end
190
-
191
- # Get the image path based on the size provided,
192
- # default is Carrierwave default (usually the real size)
193
- #
194
- # @param field_slug [string] The slug of the field setting
195
- # @param size [string] The size. It can be 'thumb' 200x200 cropped,
196
- # 'medium' 700x700 max size, 'large' 1400x1400 max size, or blank
197
- # @return [string] The url of the image
198
- def get_image_path field_slug, size = ''
199
- get_image_info( field_slug, size, 'path' )
200
- end
201
-
202
- # Get the object related to that field setting
203
- #
204
- # @param field_slug [string] The slug of the field setting
205
- # @param size [string] The size. It can be 'thumb' 200x200 cropped,
206
- # 'medium' 700x700 max size, 'large' 1400x1400 max size, or blank
207
- # @param info [string] String of the info to be retrieved
208
- # @return [string] The info requested if present
209
- # @return [boolean] Returns false if no info is found or if image isn't found
210
- def get_image_info field_slug, size, info
211
- obj = self.images.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) }
212
- # Alternative query
213
- # obj = Image.where(field_setting_id: FieldSetting.get_id( field_slug ), fieldable_id: self.id, fieldable_type: self.class.to_s ).first
214
- raise ArgumentError, "There isn't any image associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
215
- if obj.image.present?
216
- if obj.image.respond_to?(size) && %w[thumb medium large].include?(size)
217
- obj.image.send(size).send(info)
218
- else
219
- obj.image.send(info)
220
- end
221
- end
222
- end
223
-
224
- def get_image_dimension field_slug
225
- obj = self.images.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) }
226
-
227
- raise ArgumentError, "There isn't any image associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
228
- if obj.image.present?
229
- if obj.image.respond_to?(size) && %w[thumb medium large].include?(size)
230
- obj.image.send(size).send(info)
231
- else
232
- obj.image.send(info)
233
- end
234
- end
235
- end
236
-
237
- # Check if the field has an attached video
238
- #
239
- # @param field_slug [string] The slug of the field setting
240
- # @return [boolean]
241
- def has_video field_slug
242
- obj = self.videos.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) }
243
- # Alternative query
244
- # obj = Image.where(field_setting_id: FieldSetting.get_id( field_slug ), fieldable_id: self.id, fieldable_type: self.class.to_s ).first
245
- raise ArgumentError, "There isn't any video associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
246
- return obj.video.present?
247
- end
248
-
249
- # Get the video url based on the size provided,
250
- # default is Carrierwave default (usually the real size)
251
- #
252
- # @param field_slug [string] The slug of the field setting
253
- # @param size [string] The size. It can be 'thumb' 200x200 cropped,
254
- # 'medium' 700x700 max size, 'large' 1400x1400 max size, or blank
255
- # @return [string] The url of the video
256
- def get_video_url field_slug
257
- get_video_info( field_slug, 'url' )
258
- end
259
-
260
- # Get the video path based on the size provided,
261
- # default is Carrierwave default (usually the real size)
262
- #
263
- # @param field_slug [string] The slug of the field setting
264
- # @param size [string] The size. It can be 'thumb' 200x200 cropped,
265
- # 'medium' 700x700 max size, 'large' 1400x1400 max size, or blank
266
- # @return [string] The url of the video
267
- def get_video_path field_slug
268
- get_video_info( field_slug, 'path' )
269
- end
270
-
271
- # Get the object related to that field setting
272
- #
273
- # @param field_slug [string] The slug of the field setting
274
- # @param info [string] String of the info to be retrieved
275
- # @return [string] The info requested if present
276
- # @return [boolean] Returns false if no info is found or if image isn't found
277
- def get_video_info field_slug, info
278
- obj = self.videos.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) }
279
- # Alternative query
280
- # obj = video.where(field_setting_id: FieldSetting.get_id( field_slug ), fieldable_id: self.id, fieldable_type: self.class.to_s ).first
281
- raise ArgumentError, "There isn't any video associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
282
- if obj.video.present?
283
- obj.video.send(info)
284
- end
285
- end
286
-
287
- # Check if the field has an attached date
288
- #
289
- # @param field_slug [string] The slug of the field setting
290
- # @return [datetime] The date
291
- # @return [boolean] Reutrn false if nothing is found
292
- def has_date field_slug
293
- obj = self.dates.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) }
294
- raise ArgumentError, "There isn't any date associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
295
- if obj.present?
296
- return !obj.date.nil?
297
- else
298
- return false
299
- end
300
- end
301
-
302
- # Get the object related to that field setting
303
- #
304
- # @param field_slug [string] The slug of the field setting
305
- # @return [boolean]
306
- def get_date field_slug
307
- obj = self.dates.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) }
308
- raise ArgumentError, "There isn't any date associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
309
- obj.date
310
- end
311
-
312
- # Check if exists any repeater with that slug
313
- #
314
- # @param field_slug [string] The slug of the field setting
315
- # @return [boolean]
316
- def has_repeater field_slug
317
- obj = self.repeaters.find_all{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) }
318
- raise ArgumentError, "There isn't any repeater associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
319
- return obj.present?
320
- end
321
-
322
- # Get the all repeater instances
323
- #
324
- # @param field_slug [string] The slug of the field setting
325
- # @return [hash]
326
- def get_repeater field_slug
327
- obj = self.repeaters.find_all{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) }
328
- raise ArgumentError, "There isn't any repeater associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
329
- obj.sort_by(&:position)
330
- end
331
-
332
- # Get the radio choice
333
- #
334
- # If by mistake the Radio instance has many choices associated,
335
- # only the first one will be retrieved.
336
- #
337
- # @param field_slug [string] The slug of the field setting
338
- # @return [hash] A hash of containing the label and value of the selected choice. `{ label: 'the label', value: 'the value'}`
339
- def get_radio_choice field_slug
340
- field_setting = FieldSetting.find_by(slug:field_slug)
341
- obj = self.radios.find{ |t| t.field_setting_id == field_setting.id }
342
- raise ArgumentError, "There isn't any radio associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
343
- raise "There isn't any choice available for the current radio (#{field_slug}) on instance (#{self.class.name} ##{self.id})." unless field_setting.choices.any?
344
- return { label: obj.choices.first.label, value: obj.choices.first.value }
345
- end
346
-
347
- # Get the select choices
348
- #
349
- # @param field_slug [string] The slug of the field setting
350
- # @return [hash] A hash of containing the label and value of the selected choice. `{ label: 'the label', 'value': 'the value'}`
351
- def get_selection_choice field_slug
352
- field_setting = FieldSetting.find_by(slug:field_slug)
353
- obj = self.selections.find{ |t| t.field_setting_id == field_setting.id }
354
- raise ArgumentError, "There isn't any radio associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
355
- raise "There isn't any choice available for the current radio (#{field_slug}) on instance (#{self.class.name} ##{self.id})." unless field_setting.choices.any?
356
- return { label: obj.choices.first.label, value: obj.choices.first.value }
357
- end
358
-
359
- # Get the checkbox choice
360
- #
361
- # @param field_slug [string] The slug of the field setting
362
- # @return [array] An array of labels and values of the selected choices. `[{ label: '1st label', value: '1st-value'}, { label: '2nd label', value: '2nd-value'}]`
363
- def get_checkbox_choices field_slug
364
- field_setting = FieldSetting.find_by(slug:field_slug)
365
- obj = self.checkboxes.find{ |t| t.field_setting_id == field_setting.id }
366
- raise ArgumentError, "There isn't any checkbox associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
367
- raise "There isn't any choice available for the current radio (#{field_slug}) on instance (#{self.class.name} ##{self.id})." unless field_setting.choices.any?
368
- obj_array = []
369
- obj.choices.order('label').each do |o|
370
- obj_array << { label: o.label, value: o.value }
371
- end
372
- return obj_array
373
- end
374
-
375
- # Check if has related components
376
- #
377
- # @param field_slug [string] The slug of the field setting
378
- # @return [boolean]
379
- def has_related_components field_slug
380
- obj = self.relations.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) }
381
- raise ArgumentError, "There isn't any related field associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
382
- return obj.dependent_relations.any?
383
- end
384
-
385
- # Alias for has_related_components
386
- def has_dependent_components field_slug
387
- has_related_components field_slug
388
- end
389
-
390
- # Get related components
391
- #
392
- # @param field_slug [string] The slug of the field setting
393
- # @return [array] An array of components
394
- def get_related_components field_slug
395
- obj = self.relations.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) }
396
- raise ArgumentError, "There isn't any related field associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
397
- return obj.dependent_relations.map{|relation| relation.dependent}
398
- end
399
-
400
- # Alias for get_related_components
401
- def get_dependent_components field_slug
402
- get_related_components field_slug
403
- end
404
-
405
- # Get all components which owns a relation where the current instance is a dependent
406
- #
407
- # @param field_slug [string] The slug of the field setting of the relation
408
- # @return [array] An array of components and/or boards
409
- def get_owner_components field_slug
410
- # obj = self.owner_relations.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) }
411
- obj = Relation.where(field_setting_id: B.get_field_settings(field_slug)).includes(dependent_relations: :dependent).where(binda_relation_links: {dependent_type: self.class.name})
412
- raise ArgumentError, "There isn't any relation associated to the current slug (#{field_slug}) where the current instance (#{self.class.name} ##{self.id}) is a dependent.", caller if obj.nil?
413
- return obj
414
- end
415
-
416
- # Check if has related boards
417
- #
418
- # @param field_slug [string] The slug of the field setting
419
- # @return [boolean]
420
- def has_related_boards field_slug
421
- obj = self.relations.find{ |t| t.field_setting_id == FieldSetting.get_id( field_slug ) }
422
- raise ArgumentError, "There isn't any related field associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
423
- return obj.dependent_relations.any?
424
- end
425
-
426
- # Get related boards
427
- #
428
- # @param field_slug [string] The slug of the field setting
429
- # @return [array] An array of boards
430
- def get_related_boards field_slug
431
- obj = self.relations.find{ |t| t.field_setting_idid == FieldSetting.get_id( field_slug ) }
432
- raise ArgumentError, "There isn't any related field associated to the current slug (#{field_slug}) on instance (#{self.class.name} ##{self.id}).", caller if obj.nil?
433
- return obj.dependent_relations.map{|relation| relation.dependent}
434
88
  end
435
89
 
436
90
  # Find or create a field by field setting and field type
@@ -441,24 +95,9 @@ module Binda
441
95
  #
442
96
  # @param field_setting_id [string] The field setting id
443
97
  # @param field_type [string] THe field type
444
- def find_or_create_a_field_by field_setting_id, field_type
98
+ def find_or_create_a_field_by(field_setting_id, field_type)
445
99
  if FieldSetting.get_field_classes.include?( field_type.classify ) && field_setting_id.is_a?( Integer )
446
- # It's mandatory to use `select{}.first`!!!
447
- # If you use any ActiveRecord method (like `where` of `find`) the validation errors are wiped out
448
- # from the object and not rendered next to the form in the editor view
449
- obj = self.send( field_type.pluralize ).select{|rf| rf.field_setting_id == field_setting_id}.first
450
- if obj.nil?
451
- # As we are using the `select{}.first` method, asynchronous requests passing through
452
- # this method will create some inconsistentcy between this `self` object and the real object.
453
- # In other words `self` should be reloaded, but we won't reload it otherwise we will
454
- # erase the errors shipped with it initially. Therefore we will check again with `find_or_create_by!`.
455
- # This leads to another issue, which is: errors coming from asynchronous requests won't be considered
456
- # as the `self` object is the initial one, not the "updated" one. At the current time this is not
457
- # a problem because the only asynchronous requests are for brand new records which don't need validation.
458
- return self.send( field_type.pluralize ).find_or_create_by!( field_setting_id: field_setting_id )
459
- else
460
- return obj
461
- end
100
+ get_field(field_type, field_setting_id)
462
101
  else
463
102
  raise ArgumentError, "One parameter in find_or_create_a_field_by() is not correct on instance (#{self.class.name} ##{self.id}).", caller
464
103
  end
@@ -495,5 +134,29 @@ module Binda
495
134
  # TODO: Update all helpers replacing `find` method with ruby `select`.
496
135
  # This should improve performance avoiding generating useless ActiveRecord objects.
497
136
 
137
+ private
138
+
139
+ # Get field based on field type and field setting
140
+ # @param field_type [string]
141
+ # @param field_setting_id [integer]
142
+ # @return [ActiveRecord]
143
+ def get_field(field_type, field_setting_id)
144
+ # It's mandatory to use `select{}.first`!!!
145
+ # If you use any ActiveRecord method (like `where` of `find`) the validation errors are wiped out
146
+ # from the object and not rendered next to the form in the editor view
147
+ obj = self.send( field_type.pluralize ).select{|rf| rf.field_setting_id == field_setting_id}.first
148
+ if obj.nil?
149
+ # As we are using the `select{}.first` method, asynchronous requests passing through
150
+ # this method will create some inconsistentcy between this `self` object and the real object.
151
+ # In other words `self` should be reloaded, but we won't reload it otherwise we will
152
+ # erase the errors shipped with it initially. Therefore we will check again with `find_or_create_by!`.
153
+ # This leads to another issue, which is: errors coming from asynchronous requests won't be considered
154
+ # as the `self` object is the initial one, not the "updated" one. At the current time this is not
155
+ # a problem because the only asynchronous requests are for brand new records which don't need validation.
156
+ return self.send( field_type.pluralize ).find_or_create_by!( field_setting_id: field_setting_id )
157
+ else
158
+ return obj
159
+ end
160
+ end
498
161
  end
499
162
  end
@@ -1,10 +1,23 @@
1
+ <% content_for :title do %>
2
+ <%= "#{ t :edit }".capitalize %>
3
+ <%= @structure.name.humanize.split.map(&:capitalize).join(' ') %>
4
+ <% end %>
5
+
1
6
  <% content_for :header do %>
2
7
  <div class="main-header--buttons">
3
8
  <% if @structure.has_preview %>
4
- <%= link_to "<i class=\"fas fa-link\"></i>#{ t 'binda.preview' } #{ @structure.name.humanize.split.map(&:capitalize).join(' ') }".html_safe, "#{binda.root_path}#{@structure.slug}/#{@instance.slug}", class: 'main-header--link b-btn b-btn-primary' %>
9
+ <a href="<%= "#{binda.root_path}#{@structure.slug}/#{@instance.slug}" %>"
10
+ class="main-header--link b-btn b-btn-primary">
11
+ <i class="fas fa-link"></i>
12
+ <%= t 'binda.preview' %>
13
+ <%= @structure.name.humanize.split.map(&:capitalize).join(' ') %>
14
+ </a>
5
15
  <% end %>
6
16
  </div>
7
- <p class="main-header--title"><%= "#{ t :edit }".capitalize %> <%= @structure.name.humanize.split.map(&:capitalize).join(' ') %></p>
17
+ <p class="main-header--title">
18
+ <%= "#{ t :edit }".capitalize %>
19
+ <%= @structure.name.humanize.split.map(&:capitalize).join(' ') %>
20
+ </p>
8
21
  <% end %>
9
22
 
10
23
  <% content_for :content do %>