lanes 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +7 -0
- data/Gemfile +2 -2
- data/client/lanes/components/Base.coffee +12 -11
- data/client/lanes/components/enabled.js.erb +1 -1
- data/client/lanes/components/grid/Editor.coffee +2 -2
- data/client/lanes/components/grid/Grid.coffee +60 -58
- data/client/lanes/components/grid/PopOverEditor.coffee +3 -3
- data/client/lanes/components/grid/RowEditor.coffee +1 -1
- data/client/lanes/components/grid/{grid.scss → _index.scss} +0 -0
- data/client/lanes/components/grid/template.html +1 -1
- data/client/lanes/components/modal/ModalDialog.coffee +1 -1
- data/client/lanes/components/modal/{modal.scss → _index.scss} +1 -1
- data/client/lanes/components/modal/index.js +1 -1
- data/client/lanes/components/popover/PopOver.coffee +1 -1
- data/client/lanes/components/popover/_index.scss +1 -0
- data/client/lanes/components/popover/index.js +1 -1
- data/client/lanes/components/select_field/{select_field.scss → _index.scss} +0 -0
- data/client/lanes/extension/Extensions.coffee +3 -2
- data/client/lanes/lib/Templates.coffee +7 -0
- data/client/lanes/minimal.js +1 -1
- data/client/lanes/minimal.scss.erb +1 -1
- data/client/lanes/models/Base.coffee +16 -19
- data/client/lanes/models/Bootstrap.coffee +1 -2
- data/client/lanes/models/Collection.coffee +37 -25
- data/client/lanes/models/Screens.coffee +6 -18
- data/client/lanes/models/Sync.coffee +12 -5
- data/client/lanes/screens/Base.coffee +1 -2
- data/client/lanes/screens/Instance.coffee +2 -5
- data/client/lanes/screens/screen-definitions.js.erb +10 -2
- data/client/{styles → lanes/styles}/components/all.scss +0 -0
- data/client/{styles → lanes/styles}/components/changes-notification.scss +0 -0
- data/client/{styles → lanes/styles}/components/record-finder.scss +0 -0
- data/client/{styles → lanes/styles}/components/suggest.scss +0 -0
- data/client/{styles → lanes/styles}/fonts/icomoon.eot +0 -0
- data/client/{styles → lanes/styles}/fonts/icomoon.svg +0 -0
- data/client/{styles → lanes/styles}/fonts/icomoon.ttf +0 -0
- data/client/{styles → lanes/styles}/fonts/icomoon.woff +0 -0
- data/client/{styles → lanes/styles}/fonts/selection.json +0 -0
- data/client/{styles → lanes/styles}/fonts/style.scss +0 -0
- data/client/{styles → lanes/styles}/fonts.scss +5 -5
- data/client/{styles → lanes/styles}/forms.scss +0 -0
- data/client/{styles → lanes/styles}/index.css +0 -0
- data/client/{styles → lanes/styles}/keybindings.scss +0 -0
- data/client/{styles → lanes/styles}/layout.scss +0 -0
- data/client/{styles → lanes/styles}/plugins/all.scss +0 -0
- data/client/{styles → lanes/styles}/plugins/overlay.scss +0 -0
- data/client/{styles → lanes/styles}/plugins/resize-sensor.scss +0 -0
- data/client/{styles → lanes/styles}/screens.scss +0 -0
- data/client/{styles → lanes/styles}/tabs.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_alerts.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_badges.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_breadcrumbs.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_button-groups.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_buttons.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_carousel.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_close.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_code.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_component-animations.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_dropdowns.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_forms.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_glyphicons.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_grid.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_input-groups.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_jumbotron.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_labels.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_list-group.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_media.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_mixins.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_modals.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_navbar.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_navs.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_normalize.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_pager.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_pagination.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_panels.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_popovers.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_print.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_progress-bars.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_responsive-embed.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_responsive-utilities.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_scaffolding.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_tables.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_theme.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_thumbnails.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_tooltip.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_type.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_utilities.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_variables.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/_wells.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_alerts.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_background-variant.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_border-radius.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_buttons.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_center-block.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_clearfix.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_forms.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_gradients.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_grid-framework.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_grid.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_hide-text.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_image.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_labels.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_list-group.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_nav-divider.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_nav-vertical-align.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_opacity.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_pagination.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_panels.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_progress-bar.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_reset-filter.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_resize.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_responsive-visibility.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_size.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_tab-focus.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_table-row.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_text-emphasis.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_text-overflow.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_vendor-prefixes.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_alerts.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_badges.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_breadcrumbs.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_button-groups.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_buttons.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_carousel.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_close.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_code.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_component-animations.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_dropdowns.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_forms.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_glyphicons.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_grid.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_input-groups.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_jumbotron.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_labels.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_list-group.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_media.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_mixins.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_modals.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_navbar.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_navs.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_normalize.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_pager.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_pagination.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_panels.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_popovers.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_print.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_progress-bars.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_responsive-embed.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_responsive-utilities.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_scaffolding.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_tables.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_theme.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_thumbnails.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_tooltip.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_type.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_utilities.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_variables.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/_wells.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/bootstrap.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_alerts.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_background-variant.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_border-radius.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_buttons.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_center-block.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_clearfix.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_forms.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_gradients.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_grid-framework.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_grid.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_hide-text.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_image.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_labels.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_list-group.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_nav-divider.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_nav-vertical-align.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_opacity.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_pagination.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_panels.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_progress-bar.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_reset-filter.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_resize.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_responsive-visibility.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_size.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_tab-focus.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_table-row.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_text-emphasis.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_text-overflow.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_vendor-prefixes.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap-custom-grid.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap-custom-modals.scss +0 -0
- data/client/{styles → lanes/styles}/vendor/bootstrap.scss +2 -2
- data/client/{styles → lanes/styles}/vendor/dataTables.scss +0 -0
- data/client/lanes/views/Base.coffee +34 -49
- data/client/lanes/views/FormBindings.coffee +22 -20
- data/client/lanes/views/Helpers.coffee +1 -1
- data/client/lanes/views/empty-span.html +1 -0
- data/client/lanes/workspace/ActiveScreensSwitcher.coffee +8 -1
- data/client/lanes/workspace/Layout.coffee +7 -4
- data/client/lanes/workspace/Navbar.coffee +6 -2
- data/client/lanes/workspace/Pages.coffee +5 -1
- data/client/lanes/workspace/ScreensMenu.coffee +14 -2
- data/client/lanes/workspace/WorkspaceView.coffee +5 -0
- data/client/lanes/workspace/index.js +1 -0
- data/client/lanes/workspace.scss.erb +6 -1
- data/lanes.gemspec +1 -1
- data/lib/lanes/api/controller.rb +5 -7
- data/lib/lanes/api/helper_methods.rb +1 -1
- data/lib/lanes/api/javascript_processor.rb +3 -2
- data/lib/lanes/command/app.rb +8 -4
- data/lib/lanes/command/generate_model.rb +13 -11
- data/lib/lanes/command/generate_screen.rb +9 -2
- data/lib/lanes/command/generate_view.rb +15 -3
- data/lib/lanes/command/generate_view.usage +7 -7
- data/lib/lanes/command/named_command.rb +2 -2
- data/lib/lanes/command/templates/client/index.js +3 -0
- data/lib/lanes/command/templates/client/models/BaseModel.coffee +5 -0
- data/lib/lanes/command/templates/client/models/Model.coffee +1 -1
- data/lib/lanes/command/templates/client/views/BaseView.coffee +5 -0
- data/lib/lanes/command/templates/client/views/View.coffee +1 -1
- data/lib/lanes/command/templates/config/screen.rb +8 -0
- data/lib/lanes/command/templates/lib/namespace/base_model.rb +9 -0
- data/lib/lanes/command/templates/lib/namespace/model.rb +1 -1
- data/lib/lanes/command/templates/spec/client/models/ModelSpec.coffee +1 -1
- data/lib/lanes/command/templates/spec/client/views/ViewSpec.coffee +1 -1
- data/lib/lanes/command.rb +1 -2
- data/lib/lanes/components.rb +5 -4
- data/lib/lanes/concerns/all.rb +0 -5
- data/lib/lanes/concerns/attr_accessor_with_default.rb +5 -3
- data/lib/lanes/concerns/set_attribute_data.rb +6 -23
- data/lib/lanes/configuration.rb +1 -0
- data/lib/lanes/extension.rb +19 -10
- data/lib/lanes/guard_tasks.rb +1 -1
- data/lib/lanes/model.rb +1 -6
- data/lib/lanes/{screens.rb → screen.rb} +40 -23
- data/lib/lanes/spec_helper.rb +4 -2
- data/lib/lanes/version.rb +1 -1
- data/lib/lanes.rb +1 -1
- data/spec/api/javascript_processor_spec.rb +3 -3
- data/spec/command_spec.rb +49 -0
- data/spec/concerns/attr_accessor_with_default_spec.rb +7 -0
- data/spec/helpers/lanes-helpers.coffee +46 -22
- data/spec/helpers/minitest_assertions.rb +23 -0
- data/spec/lanes/models/BaseSpec.coffee +57 -56
- data/spec/lanes/models/CollectionSpec.coffee +14 -0
- data/spec/lanes/models/PubSubSpec.coffee +5 -5
- data/spec/lanes/views/BaseSpec.coffee +32 -31
- data/spec/lanes/views/FormBindingsSpec.coffee +32 -0
- metadata +183 -179
- data/client/lanes/components/popover/popover.scss +0 -1
- data/lib/lanes/command/templates/lib/namespace/screen.rb +0 -17
- data/lib/lanes/concerns/code_identifier.rb +0 -43
- data/lib/lanes/concerns/immutable_model.rb +0 -32
- data/lib/lanes/concerns/locked_fields.rb +0 -84
- data/lib/lanes/concerns/random_hash_code.rb +0 -40
- data/lib/lanes/concerns/visible_id_identifier.rb +0 -53
- 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
|