lanes 0.1.0 → 0.1.2

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 (257) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +7 -0
  3. data/Gemfile +2 -2
  4. data/client/lanes/components/Base.coffee +12 -11
  5. data/client/lanes/components/enabled.js.erb +1 -1
  6. data/client/lanes/components/grid/Editor.coffee +2 -2
  7. data/client/lanes/components/grid/Grid.coffee +60 -58
  8. data/client/lanes/components/grid/PopOverEditor.coffee +3 -3
  9. data/client/lanes/components/grid/RowEditor.coffee +1 -1
  10. data/client/lanes/components/grid/{grid.scss → _index.scss} +0 -0
  11. data/client/lanes/components/grid/template.html +1 -1
  12. data/client/lanes/components/modal/ModalDialog.coffee +1 -1
  13. data/client/lanes/components/modal/{modal.scss → _index.scss} +1 -1
  14. data/client/lanes/components/modal/index.js +1 -1
  15. data/client/lanes/components/popover/PopOver.coffee +1 -1
  16. data/client/lanes/components/popover/_index.scss +1 -0
  17. data/client/lanes/components/popover/index.js +1 -1
  18. data/client/lanes/components/select_field/{select_field.scss → _index.scss} +0 -0
  19. data/client/lanes/extension/Extensions.coffee +3 -2
  20. data/client/lanes/lib/Templates.coffee +7 -0
  21. data/client/lanes/minimal.js +1 -1
  22. data/client/lanes/minimal.scss.erb +1 -1
  23. data/client/lanes/models/Base.coffee +16 -19
  24. data/client/lanes/models/Bootstrap.coffee +1 -2
  25. data/client/lanes/models/Collection.coffee +37 -25
  26. data/client/lanes/models/Screens.coffee +6 -18
  27. data/client/lanes/models/Sync.coffee +12 -5
  28. data/client/lanes/screens/Base.coffee +1 -2
  29. data/client/lanes/screens/Instance.coffee +2 -5
  30. data/client/lanes/screens/screen-definitions.js.erb +10 -2
  31. data/client/{styles → lanes/styles}/components/all.scss +0 -0
  32. data/client/{styles → lanes/styles}/components/changes-notification.scss +0 -0
  33. data/client/{styles → lanes/styles}/components/record-finder.scss +0 -0
  34. data/client/{styles → lanes/styles}/components/suggest.scss +0 -0
  35. data/client/{styles → lanes/styles}/fonts/icomoon.eot +0 -0
  36. data/client/{styles → lanes/styles}/fonts/icomoon.svg +0 -0
  37. data/client/{styles → lanes/styles}/fonts/icomoon.ttf +0 -0
  38. data/client/{styles → lanes/styles}/fonts/icomoon.woff +0 -0
  39. data/client/{styles → lanes/styles}/fonts/selection.json +0 -0
  40. data/client/{styles → lanes/styles}/fonts/style.scss +0 -0
  41. data/client/{styles → lanes/styles}/fonts.scss +5 -5
  42. data/client/{styles → lanes/styles}/forms.scss +0 -0
  43. data/client/{styles → lanes/styles}/index.css +0 -0
  44. data/client/{styles → lanes/styles}/keybindings.scss +0 -0
  45. data/client/{styles → lanes/styles}/layout.scss +0 -0
  46. data/client/{styles → lanes/styles}/plugins/all.scss +0 -0
  47. data/client/{styles → lanes/styles}/plugins/overlay.scss +0 -0
  48. data/client/{styles → lanes/styles}/plugins/resize-sensor.scss +0 -0
  49. data/client/{styles → lanes/styles}/screens.scss +0 -0
  50. data/client/{styles → lanes/styles}/tabs.scss +0 -0
  51. data/client/{styles → lanes/styles}/vendor/bootstrap/_alerts.scss +0 -0
  52. data/client/{styles → lanes/styles}/vendor/bootstrap/_badges.scss +0 -0
  53. data/client/{styles → lanes/styles}/vendor/bootstrap/_breadcrumbs.scss +0 -0
  54. data/client/{styles → lanes/styles}/vendor/bootstrap/_button-groups.scss +0 -0
  55. data/client/{styles → lanes/styles}/vendor/bootstrap/_buttons.scss +0 -0
  56. data/client/{styles → lanes/styles}/vendor/bootstrap/_carousel.scss +0 -0
  57. data/client/{styles → lanes/styles}/vendor/bootstrap/_close.scss +0 -0
  58. data/client/{styles → lanes/styles}/vendor/bootstrap/_code.scss +0 -0
  59. data/client/{styles → lanes/styles}/vendor/bootstrap/_component-animations.scss +0 -0
  60. data/client/{styles → lanes/styles}/vendor/bootstrap/_dropdowns.scss +0 -0
  61. data/client/{styles → lanes/styles}/vendor/bootstrap/_forms.scss +0 -0
  62. data/client/{styles → lanes/styles}/vendor/bootstrap/_glyphicons.scss +0 -0
  63. data/client/{styles → lanes/styles}/vendor/bootstrap/_grid.scss +0 -0
  64. data/client/{styles → lanes/styles}/vendor/bootstrap/_input-groups.scss +0 -0
  65. data/client/{styles → lanes/styles}/vendor/bootstrap/_jumbotron.scss +0 -0
  66. data/client/{styles → lanes/styles}/vendor/bootstrap/_labels.scss +0 -0
  67. data/client/{styles → lanes/styles}/vendor/bootstrap/_list-group.scss +0 -0
  68. data/client/{styles → lanes/styles}/vendor/bootstrap/_media.scss +0 -0
  69. data/client/{styles → lanes/styles}/vendor/bootstrap/_mixins.scss +0 -0
  70. data/client/{styles → lanes/styles}/vendor/bootstrap/_modals.scss +0 -0
  71. data/client/{styles → lanes/styles}/vendor/bootstrap/_navbar.scss +0 -0
  72. data/client/{styles → lanes/styles}/vendor/bootstrap/_navs.scss +0 -0
  73. data/client/{styles → lanes/styles}/vendor/bootstrap/_normalize.scss +0 -0
  74. data/client/{styles → lanes/styles}/vendor/bootstrap/_pager.scss +0 -0
  75. data/client/{styles → lanes/styles}/vendor/bootstrap/_pagination.scss +0 -0
  76. data/client/{styles → lanes/styles}/vendor/bootstrap/_panels.scss +0 -0
  77. data/client/{styles → lanes/styles}/vendor/bootstrap/_popovers.scss +0 -0
  78. data/client/{styles → lanes/styles}/vendor/bootstrap/_print.scss +0 -0
  79. data/client/{styles → lanes/styles}/vendor/bootstrap/_progress-bars.scss +0 -0
  80. data/client/{styles → lanes/styles}/vendor/bootstrap/_responsive-embed.scss +0 -0
  81. data/client/{styles → lanes/styles}/vendor/bootstrap/_responsive-utilities.scss +0 -0
  82. data/client/{styles → lanes/styles}/vendor/bootstrap/_scaffolding.scss +0 -0
  83. data/client/{styles → lanes/styles}/vendor/bootstrap/_tables.scss +0 -0
  84. data/client/{styles → lanes/styles}/vendor/bootstrap/_theme.scss +0 -0
  85. data/client/{styles → lanes/styles}/vendor/bootstrap/_thumbnails.scss +0 -0
  86. data/client/{styles → lanes/styles}/vendor/bootstrap/_tooltip.scss +0 -0
  87. data/client/{styles → lanes/styles}/vendor/bootstrap/_type.scss +0 -0
  88. data/client/{styles → lanes/styles}/vendor/bootstrap/_utilities.scss +0 -0
  89. data/client/{styles → lanes/styles}/vendor/bootstrap/_variables.scss +0 -0
  90. data/client/{styles → lanes/styles}/vendor/bootstrap/_wells.scss +0 -0
  91. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_alerts.scss +0 -0
  92. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_background-variant.scss +0 -0
  93. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_border-radius.scss +0 -0
  94. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_buttons.scss +0 -0
  95. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_center-block.scss +0 -0
  96. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_clearfix.scss +0 -0
  97. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_forms.scss +0 -0
  98. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_gradients.scss +0 -0
  99. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_grid-framework.scss +0 -0
  100. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_grid.scss +0 -0
  101. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_hide-text.scss +0 -0
  102. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_image.scss +0 -0
  103. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_labels.scss +0 -0
  104. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_list-group.scss +0 -0
  105. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_nav-divider.scss +0 -0
  106. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_nav-vertical-align.scss +0 -0
  107. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_opacity.scss +0 -0
  108. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_pagination.scss +0 -0
  109. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_panels.scss +0 -0
  110. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_progress-bar.scss +0 -0
  111. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_reset-filter.scss +0 -0
  112. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_resize.scss +0 -0
  113. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_responsive-visibility.scss +0 -0
  114. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_size.scss +0 -0
  115. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_tab-focus.scss +0 -0
  116. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_table-row.scss +0 -0
  117. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_text-emphasis.scss +0 -0
  118. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_text-overflow.scss +0 -0
  119. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_vendor-prefixes.scss +0 -0
  120. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_alerts.scss +0 -0
  121. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_badges.scss +0 -0
  122. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_breadcrumbs.scss +0 -0
  123. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_button-groups.scss +0 -0
  124. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_buttons.scss +0 -0
  125. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_carousel.scss +0 -0
  126. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_close.scss +0 -0
  127. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_code.scss +0 -0
  128. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_component-animations.scss +0 -0
  129. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_dropdowns.scss +0 -0
  130. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_forms.scss +0 -0
  131. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_glyphicons.scss +0 -0
  132. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_grid.scss +0 -0
  133. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_input-groups.scss +0 -0
  134. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_jumbotron.scss +0 -0
  135. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_labels.scss +0 -0
  136. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_list-group.scss +0 -0
  137. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_media.scss +0 -0
  138. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_mixins.scss +0 -0
  139. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_modals.scss +0 -0
  140. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_navbar.scss +0 -0
  141. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_navs.scss +0 -0
  142. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_normalize.scss +0 -0
  143. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_pager.scss +0 -0
  144. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_pagination.scss +0 -0
  145. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_panels.scss +0 -0
  146. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_popovers.scss +0 -0
  147. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_print.scss +0 -0
  148. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_progress-bars.scss +0 -0
  149. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_responsive-embed.scss +0 -0
  150. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_responsive-utilities.scss +0 -0
  151. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_scaffolding.scss +0 -0
  152. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_tables.scss +0 -0
  153. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_theme.scss +0 -0
  154. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_thumbnails.scss +0 -0
  155. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_tooltip.scss +0 -0
  156. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_type.scss +0 -0
  157. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_utilities.scss +0 -0
  158. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_variables.scss +0 -0
  159. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_wells.scss +0 -0
  160. data/client/{styles → lanes/styles}/vendor/bootstrap/old/bootstrap.scss +0 -0
  161. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_alerts.scss +0 -0
  162. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_background-variant.scss +0 -0
  163. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_border-radius.scss +0 -0
  164. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_buttons.scss +0 -0
  165. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_center-block.scss +0 -0
  166. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_clearfix.scss +0 -0
  167. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_forms.scss +0 -0
  168. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_gradients.scss +0 -0
  169. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_grid-framework.scss +0 -0
  170. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_grid.scss +0 -0
  171. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_hide-text.scss +0 -0
  172. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_image.scss +0 -0
  173. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_labels.scss +0 -0
  174. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_list-group.scss +0 -0
  175. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_nav-divider.scss +0 -0
  176. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_nav-vertical-align.scss +0 -0
  177. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_opacity.scss +0 -0
  178. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_pagination.scss +0 -0
  179. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_panels.scss +0 -0
  180. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_progress-bar.scss +0 -0
  181. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_reset-filter.scss +0 -0
  182. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_resize.scss +0 -0
  183. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_responsive-visibility.scss +0 -0
  184. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_size.scss +0 -0
  185. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_tab-focus.scss +0 -0
  186. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_table-row.scss +0 -0
  187. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_text-emphasis.scss +0 -0
  188. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_text-overflow.scss +0 -0
  189. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_vendor-prefixes.scss +0 -0
  190. data/client/{styles → lanes/styles}/vendor/bootstrap-custom-grid.scss +0 -0
  191. data/client/{styles → lanes/styles}/vendor/bootstrap-custom-modals.scss +0 -0
  192. data/client/{styles → lanes/styles}/vendor/bootstrap.scss +2 -2
  193. data/client/{styles → lanes/styles}/vendor/dataTables.scss +0 -0
  194. data/client/lanes/views/Base.coffee +34 -49
  195. data/client/lanes/views/FormBindings.coffee +22 -20
  196. data/client/lanes/views/Helpers.coffee +1 -1
  197. data/client/lanes/views/empty-span.html +1 -0
  198. data/client/lanes/workspace/ActiveScreensSwitcher.coffee +8 -1
  199. data/client/lanes/workspace/Layout.coffee +7 -4
  200. data/client/lanes/workspace/Navbar.coffee +6 -2
  201. data/client/lanes/workspace/Pages.coffee +5 -1
  202. data/client/lanes/workspace/ScreensMenu.coffee +14 -2
  203. data/client/lanes/workspace/WorkspaceView.coffee +5 -0
  204. data/client/lanes/workspace/index.js +1 -0
  205. data/client/lanes/workspace.scss.erb +6 -1
  206. data/lanes.gemspec +1 -1
  207. data/lib/lanes/api/controller.rb +5 -7
  208. data/lib/lanes/api/helper_methods.rb +1 -1
  209. data/lib/lanes/api/javascript_processor.rb +3 -2
  210. data/lib/lanes/command/app.rb +8 -4
  211. data/lib/lanes/command/generate_model.rb +13 -11
  212. data/lib/lanes/command/generate_screen.rb +9 -2
  213. data/lib/lanes/command/generate_view.rb +15 -3
  214. data/lib/lanes/command/generate_view.usage +7 -7
  215. data/lib/lanes/command/named_command.rb +2 -2
  216. data/lib/lanes/command/templates/client/index.js +3 -0
  217. data/lib/lanes/command/templates/client/models/BaseModel.coffee +5 -0
  218. data/lib/lanes/command/templates/client/models/Model.coffee +1 -1
  219. data/lib/lanes/command/templates/client/views/BaseView.coffee +5 -0
  220. data/lib/lanes/command/templates/client/views/View.coffee +1 -1
  221. data/lib/lanes/command/templates/config/screen.rb +8 -0
  222. data/lib/lanes/command/templates/lib/namespace/base_model.rb +9 -0
  223. data/lib/lanes/command/templates/lib/namespace/model.rb +1 -1
  224. data/lib/lanes/command/templates/spec/client/models/ModelSpec.coffee +1 -1
  225. data/lib/lanes/command/templates/spec/client/views/ViewSpec.coffee +1 -1
  226. data/lib/lanes/command.rb +1 -2
  227. data/lib/lanes/components.rb +5 -4
  228. data/lib/lanes/concerns/all.rb +0 -5
  229. data/lib/lanes/concerns/attr_accessor_with_default.rb +5 -3
  230. data/lib/lanes/concerns/set_attribute_data.rb +6 -23
  231. data/lib/lanes/configuration.rb +1 -0
  232. data/lib/lanes/extension.rb +19 -10
  233. data/lib/lanes/guard_tasks.rb +1 -1
  234. data/lib/lanes/model.rb +1 -6
  235. data/lib/lanes/{screens.rb → screen.rb} +40 -23
  236. data/lib/lanes/spec_helper.rb +4 -2
  237. data/lib/lanes/version.rb +1 -1
  238. data/lib/lanes.rb +1 -1
  239. data/spec/api/javascript_processor_spec.rb +3 -3
  240. data/spec/command_spec.rb +49 -0
  241. data/spec/concerns/attr_accessor_with_default_spec.rb +7 -0
  242. data/spec/helpers/lanes-helpers.coffee +46 -22
  243. data/spec/helpers/minitest_assertions.rb +23 -0
  244. data/spec/lanes/models/BaseSpec.coffee +57 -56
  245. data/spec/lanes/models/CollectionSpec.coffee +14 -0
  246. data/spec/lanes/models/PubSubSpec.coffee +5 -5
  247. data/spec/lanes/views/BaseSpec.coffee +32 -31
  248. data/spec/lanes/views/FormBindingsSpec.coffee +32 -0
  249. metadata +183 -179
  250. data/client/lanes/components/popover/popover.scss +0 -1
  251. data/lib/lanes/command/templates/lib/namespace/screen.rb +0 -17
  252. data/lib/lanes/concerns/code_identifier.rb +0 -43
  253. data/lib/lanes/concerns/immutable_model.rb +0 -32
  254. data/lib/lanes/concerns/locked_fields.rb +0 -84
  255. data/lib/lanes/concerns/random_hash_code.rb +0 -40
  256. data/lib/lanes/concerns/visible_id_identifier.rb +0 -53
  257. data/spec/concerns/code_identifier_spec.rb +0 -45
@@ -1,84 +0,0 @@
1
- module Lanes
2
- module Concerns
3
-
4
- # @see ClassMethods
5
- module LockedFields
6
- extend ActiveSupport::Concern
7
-
8
- module ClassMethods
9
- # Mark fields as locked, meaning they cannot be updated by using the
10
- # regular attribute update methods. Instead it must be called in an unlock block
11
- # Relies on attr_readonly internally
12
- #
13
- # Is used to designate sensitive fields that we want to make sure someone's thought about before updating
14
- # Also solves the age old single equals vs double equals bug/typo.
15
- #
16
- # class BankAccount < Lanes::Model
17
- #
18
- # end
19
- #
20
- # bank=BankAccount.find(1)
21
- # b.mark_as_super if bank.account_balance = 42 # a bit contrived, but you get the idea
22
- # b.save # oops, what's our balance now?
23
- #
24
- # Now let's try it again with locked_fields
25
- #
26
- # class BankAccount < Lanes::Model
27
- # attr_readonly :account_balance
28
- # end
29
- #
30
- # bank=BankAccount.find(1)
31
- # b.mark_as_super if bank.account_balance = 42
32
- # b.save # Still not ideal since we marked the bank as super, but at least our balance is ok
33
- #
34
- # To update the balance we'd need to:
35
- #
36
- # b.unlock_fields( :account_balance ) do
37
- # b.account_balance += 33
38
- # end
39
- # b.save
40
- #
41
- # This is still a bit contrived since we'd actually have
42
- # an audit logger that would be involved and it'd be inside a transaction.
43
-
44
- def locked_fields( *flds )
45
- include InstanceMethods
46
- attr_readonly( *flds )
47
- end
48
-
49
- def has_locks( *locks )
50
- locks.each do | lock |
51
- define_method( "unlock_#{lock}" ) do | &block |
52
- instance_variable_set "@_lock_#{lock}_unlocked", true
53
- block.call
54
- remove_instance_variable "@_lock_#{lock}_unlocked"
55
- end
56
- define_method( "is_#{lock}_unlocked?") do
57
- instance_variable_defined? "@_lock_#{lock}_unlocked"
58
- end
59
- end
60
- end
61
-
62
- end
63
-
64
- module InstanceMethods
65
- # Unlock the field for updates inside the block
66
- # yields, then restores it.
67
- # Is class wide, meaning it Will temporarily open all instances of the class up for access in a threaded environment
68
- def unlock_fields( *flds, &block )
69
- attr_syms = flds.map(&:to_s)
70
-
71
- self.class.attr_readonly.subtract( attr_syms )
72
-
73
- yield
74
-
75
- attr_syms.each do | fld |
76
- self.class.attr_readonly.add( fld )
77
- end
78
-
79
- end
80
- end
81
-
82
- end
83
- end
84
- end
@@ -1,40 +0,0 @@
1
- module Lanes
2
- module Concerns
3
-
4
- # @see ClassMethods
5
- module RandomHashCode
6
-
7
- extend ActiveSupport::Concern
8
-
9
- # ### Random Hash Code Concern
10
- # This adds the {#has_random_hash_code} class method
11
- module ClassMethods
12
-
13
- # A random string that identifies an entity, such as a Customer, or Vendor
14
- # The code is generated by {Lanes::Strings.random} for new records
15
- # It's useful for generating *magic* links for access to an entity that cannot be guessed.
16
- # @param field_name [Symbol] which field should the hash_code be stored in
17
- # @param length [Integer] how long the hash_code should be
18
-
19
- def has_random_hash_code( field_name: :hash_code, length: 12 )
20
-
21
- validates field_name, :presence=>{
22
- :message=>"hash code is not set (should be automatically chosen)"
23
- }
24
-
25
- scope :with_hash_code, lambda{ | code |
26
- where({ :hash_code=>code })
27
- }
28
-
29
- before_validation(:on=>:create) do
30
- self[ field_name ] = Lanes::Strings.random( length ) if self[ field_name ].blank?
31
- end
32
-
33
- end
34
- end
35
-
36
- end
37
-
38
- end
39
-
40
- end
@@ -1,53 +0,0 @@
1
- module Lanes
2
- module Concerns
3
-
4
- # @see ClassMethods
5
- module VisibleIdIdentifier
6
-
7
- extend ActiveSupport::Concern
8
-
9
- module InstanceMethods
10
-
11
- # setup the visible id to the next available #{Lanes::SequentialId}
12
- # @return [Integer] the assigned ID
13
- def assign_visible_id!
14
- self.visible_id = Lanes::SequentialId.next_for( self.class )
15
- end
16
- end
17
-
18
-
19
- # ### Visible ID Identifier Concern
20
- # This adds the {#has_visible_id} class methods
21
- module ClassMethods
22
-
23
- # An auto-incrementing number that's user-visible.
24
- # The visible_id is stored as an integer, but a string index is generated for
25
- # querying by the sql like operator. The **with_visible_id** scope is available for this purpose
26
- #
27
- # The next number an also be adjusted by the end-user by setting {Lanes::SequentialId}
28
- # so they can set the numbers to start at
29
- # a specific point, which is useful for getting Invoice and other
30
- # numbers to match up to a legacy system
31
- def has_visible_id
32
- include InstanceMethods
33
- validates :visible_id, :presence=>{
34
- :message=>"ID was not set (should be automatically chosen)"
35
- }
36
- alias_attribute :record_identifier, :visible_id
37
- before_validation :assign_visible_id!, :on=>:create
38
-
39
- export_scope :with_visible_id, lambda{ | visid |
40
- if visid.to_s =~/%/
41
- where( 'cast(visible_id as varchar) like ?', visid.to_s )
42
- else
43
- where( 'cast(visible_id as varchar) = ?', visid.to_s )
44
- end
45
- }
46
-
47
- end
48
-
49
- end
50
- end
51
-
52
- end
53
- end
@@ -1,45 +0,0 @@
1
- require "lanes/spec_helper"
2
-
3
-
4
- class CodeIdentifierTest < Lanes::TestCase
5
-
6
- class CodeIdentifierTestModel
7
- class_attribute :blocks
8
- attr_accessor :code
9
-
10
- include Lanes::Concerns::CodeIdentifier
11
-
12
- def self.before_validation( opts={}, &block )
13
- self.blocks||=[]
14
- self.blocks.push( block )
15
- end
16
-
17
- def self.validates( *opts )
18
- end
19
-
20
- def run_validations
21
- self.class.blocks.each{ |b| self.instance_eval(&b) }
22
- end
23
-
24
- def [](name)
25
- :name == name ? 'A Long String of Nonsense' : ''
26
- end
27
-
28
- has_code_identifier :from => :name
29
- end
30
-
31
- def test_that_it_uppercases
32
- ci = CodeIdentifierTestModel.new
33
- ci.code='test'
34
- ci.run_validations
35
- assert_equal 'TEST', ci.code
36
- end
37
-
38
- def test_that_it_generates
39
- ci = CodeIdentifierTestModel.new
40
- ci.run_validations
41
- assert ci.code.present?, "Code wasn't auto-generated"
42
- assert_equal 'ALOSTOFNON', ci.code
43
- end
44
-
45
- end