lanes 0.6.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/client/lanes/Config.coffee +26 -9
- data/client/lanes/access/screens/user-management/UserManagement.cjsx +1 -1
- data/client/lanes/components/grid/EditingMixin.cjsx +8 -4
- data/client/lanes/components/grid/PopOverMixin.cjsx +7 -1
- data/client/lanes/components/modal/Modal.cjsx +11 -1
- data/client/lanes/components/record-finder/RecordFinder.cjsx +8 -4
- data/client/lanes/components/shared/DateTime.cjsx +8 -6
- data/client/lanes/components/shared/FieldMixin.cjsx +3 -3
- data/client/lanes/components/shared/Icon.cjsx +1 -1
- data/client/lanes/components/shared/ImageAsset.cjsx +23 -11
- data/client/lanes/components/shared/NetworkActivityOverlay.cjsx +2 -0
- data/client/lanes/extension/Base.coffee +2 -0
- data/client/lanes/fonts/fontawesome-webfont.woff +0 -0
- data/client/lanes/fonts/fontawesome-webfont.woff2 +0 -0
- data/client/lanes/lib/RequestAssets.coffee +30 -0
- data/client/lanes/lib/all.js +1 -0
- data/client/lanes/lib/loader.js +93 -0
- data/client/lanes/lib/utilFunctions.coffee +12 -0
- data/client/lanes/models/Asset.coffee +3 -4
- data/client/lanes/models/AssociationMap.coffee +17 -6
- data/client/lanes/models/Base.coffee +20 -13
- data/client/lanes/models/Collection.coffee +4 -1
- data/client/lanes/models/PubSub.coffee +2 -3
- data/client/lanes/models/SmtpSettings.coffee +7 -0
- data/client/lanes/models/Sync.coffee +2 -2
- data/client/lanes/react/Viewport.coffee +14 -10
- data/client/lanes/react/mixins/FieldErrors.coffee +3 -4
- data/client/lanes/react/mixins/ReadEditingState.coffee +1 -0
- data/client/lanes/remote/Bootstrap.coffee +85 -0
- data/client/lanes/remote/api.coffee +2 -1
- data/client/lanes/remote/onDocumentReady.coffee +12 -0
- data/client/lanes/screens/Definitions.coffee +29 -12
- data/client/lanes/screens/SystemSettings.cjsx +12 -3
- data/client/lanes/styles/fonts/_bordered-pulled.scss +9 -0
- data/client/lanes/styles/fonts/_core.scss +1 -2
- data/client/lanes/styles/fonts/_icons.scss +56 -0
- data/client/lanes/styles/fonts/_mixins.scss +37 -4
- data/client/lanes/styles/fonts/_path.scss +2 -2
- data/client/lanes/styles/fonts/_screen-reader.scss +5 -0
- data/client/lanes/styles/fonts/_variables.scss +58 -2
- data/client/lanes/styles/fonts/font-awesome.scss +3 -1
- data/client/lanes/vendor/development/calendar.js +56 -57
- data/client/lanes/vendor/development/commons.js +31319 -29618
- data/client/lanes/vendor/development/data.js +8468 -7607
- data/client/lanes/vendor/development/helpers.js +265 -131
- data/client/lanes/vendor/development/toggle.js +288 -184
- data/client/lanes/vendor/development/ui.js +3387 -3492
- data/client/lanes/vendor/development/widgets.js +972 -1229
- data/client/lanes/vendor/production/calendar.js +60 -61
- data/client/lanes/vendor/production/commons.js +30695 -29032
- data/client/lanes/vendor/production/data.js +8457 -7598
- data/client/lanes/vendor/production/toggle.js +288 -184
- data/client/lanes/vendor/production/ui.js +3264 -3373
- data/client/lanes/vendor/production/widgets.js +972 -1229
- data/client/lanes/vendor/standalone/index.js +21106 -18761
- data/client/lanes/vendor/styles/toggle.scss +4 -3
- data/client/lanes/workspace/ScreenView.cjsx +2 -2
- data/client/lanes/workspace/styles/header.scss +4 -0
- data/config/routes.rb +0 -2
- data/db/migrate/01_create_system_settings.rb +1 -1
- data/db/migrate/02_create_assets.rb +1 -1
- data/lanes.gemspec +1 -0
- data/lib/lanes.rb +1 -0
- data/lib/lanes/access/track_modifications.rb +4 -2
- data/lib/lanes/api.rb +1 -0
- data/lib/lanes/api/cable.rb +11 -3
- data/lib/lanes/api/controller_base.rb +23 -19
- data/lib/lanes/api/default_routes.rb +9 -1
- data/lib/lanes/api/generic_controller.rb +1 -1
- data/lib/lanes/api/handlers/asset.rb +2 -3
- data/lib/lanes/api/helper_methods.rb +5 -11
- data/lib/lanes/api/pub_sub.rb +13 -7
- data/lib/lanes/api/request_wrapper.rb +1 -1
- data/lib/lanes/api/routing.rb +10 -7
- data/lib/lanes/api/to_json.rb +7 -0
- data/lib/lanes/asset.rb +4 -1
- data/lib/lanes/concerns/set_attribute_data.rb +2 -1
- data/lib/lanes/extension.rb +3 -1
- data/lib/lanes/mailer.rb +40 -0
- data/lib/lanes/rake_tasks.rb +4 -0
- data/lib/lanes/spec_helper.rb +11 -3
- data/lib/lanes/system_settings.rb +22 -9
- data/lib/lanes/version.rb +1 -1
- data/lib/lanes/workspace/extension.rb +5 -0
- data/npm-build/package.json +2 -2
- data/npm-build/react-toggle.js +1 -1
- data/npm-build/standalone.js +3 -0
- data/spec/command-reference-files/initial/Gemfile +1 -1
- data/spec/command-reference-files/initial/client/appy-app/Extension.coffee +2 -1
- data/spec/command-reference-files/model/db/migrate/20150218032025_create_test_tests.rb +1 -1
- data/spec/command-reference-files/screen/client/appy-app/Extension.coffee +2 -1
- data/spec/fixtures/system_settings.yml +8 -1
- data/spec/server/mailer_spec.rb +33 -0
- data/spec/server/system_settings_spec.rb +16 -0
- data/templates/client/Extension.coffee +2 -1
- data/templates/config/database.yml +1 -1
- data/templates/db/create_table_migration.rb +1 -1
- metadata +27 -6
- data/client/fonts/fontawesome-webfont.woff +0 -0
- data/client/fonts/fontawesome-webfont.woff2 +0 -0
- data/client/lanes/lib/loader.coffee +0 -100
- data/client/lanes/workspace/Modal.cjsx +0 -47
@@ -29,6 +29,7 @@
|
|
29
29
|
}
|
30
30
|
|
31
31
|
.react-toggle--disabled {
|
32
|
+
cursor: not-allowed;
|
32
33
|
opacity: 0.5;
|
33
34
|
-webkit-transition: opacity 0.25s;
|
34
35
|
transition: opacity 0.25s;
|
@@ -45,7 +46,7 @@
|
|
45
46
|
transition: all 0.2s ease;
|
46
47
|
}
|
47
48
|
|
48
|
-
.react-toggle:hover .react-toggle-track {
|
49
|
+
.react-toggle:hover:not(.react-toggle--disabled) .react-toggle-track {
|
49
50
|
background-color: #000000;
|
50
51
|
}
|
51
52
|
|
@@ -53,7 +54,7 @@
|
|
53
54
|
background-color: #19AB27;
|
54
55
|
}
|
55
56
|
|
56
|
-
.react-toggle.react-toggle--
|
57
|
+
.react-toggle--checked:hover:not(.react-toggle--disabled) .react-toggle-track {
|
57
58
|
background-color: #128D15;
|
58
59
|
}
|
59
60
|
|
@@ -131,7 +132,7 @@
|
|
131
132
|
box-shadow: 0px 0px 2px 3px #0099E0;
|
132
133
|
}
|
133
134
|
|
134
|
-
.react-toggle:active .react-toggle-thumb {
|
135
|
+
.react-toggle:active:not(.react-toggle--disabled) .react-toggle-thumb {
|
135
136
|
-webkit-box-shadow: 0px 0px 5px 5px #0099E0;
|
136
137
|
-moz-box-shadow: 0px 0px 5px 5px #0099E0;
|
137
138
|
box-shadow: 0px 0px 5px 5px #0099E0;
|
@@ -25,7 +25,7 @@ class Lanes.Workspace.ScreenView extends Lanes.React.Component
|
|
25
25
|
|
26
26
|
renderLoading: ->
|
27
27
|
screen = Lanes.Screens.Definitions.all.findWhere(loading: true)
|
28
|
-
<LC.NetworkActivityOverlay visible
|
28
|
+
<LC.NetworkActivityOverlay visible message="Loading #{screen.title}…" />
|
29
29
|
|
30
30
|
BaseView: ->
|
31
31
|
Base = Lanes.Extensions.controlling().initialScreen?() or Lanes.Workspace.FirstRun
|
@@ -36,6 +36,6 @@ class Lanes.Workspace.ScreenView extends Lanes.React.Component
|
|
36
36
|
render: ->
|
37
37
|
child = if @displaying.isEmpty() then <@BaseView /> else @displaying.map(@renderScreen)
|
38
38
|
<div className={"page-content #{@context.uistate.layout_size}"}>
|
39
|
-
{@renderLoading() if
|
39
|
+
{@renderLoading() if @allScreens.isLoading()}
|
40
40
|
{child}
|
41
41
|
</div>
|
@@ -28,10 +28,14 @@
|
|
28
28
|
text-shadow: rgb(143, 112, 112) 2px 2px 4px;
|
29
29
|
padding: 0;
|
30
30
|
overflow: hidden;
|
31
|
+
display: flex;
|
32
|
+
align-items: center;
|
33
|
+
justify-content: center;
|
31
34
|
img {
|
32
35
|
width: 100%;
|
33
36
|
height: 100%;
|
34
37
|
}
|
38
|
+
|
35
39
|
}
|
36
40
|
|
37
41
|
.navbar-toggle, .screens-menu-toggle {
|
data/config/routes.rb
CHANGED
data/lanes.gemspec
CHANGED
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.add_dependency "activejob", "~> 5.0"
|
28
28
|
spec.add_dependency "activerecord", "~> 5.0"
|
29
29
|
spec.add_dependency "actioncable", "~> 5.0"
|
30
|
+
spec.add_dependency "mail", "~> 2.6"
|
30
31
|
|
31
32
|
spec.add_dependency "sinatra", "~> 2.0.0.beta2"
|
32
33
|
spec.add_dependency "rack", "~> 2.0"
|
data/lib/lanes.rb
CHANGED
@@ -5,7 +5,10 @@ module Lanes::Concerns
|
|
5
5
|
# The class_name for the created_by and updated_by is set to {Lanes::Configuration#user_model}
|
6
6
|
module TrackModifications
|
7
7
|
extend ActiveSupport::Concern
|
8
|
-
|
8
|
+
ApiAttributeAccess::DEFAULT_BLACKLISTED.merge(
|
9
|
+
created_at: nil, updated_at: nil,
|
10
|
+
created_by_id: nil, updated_by_id: nil
|
11
|
+
)
|
9
12
|
included do
|
10
13
|
class_attribute :record_modifications, :instance_writer=>false
|
11
14
|
self.record_modifications = true
|
@@ -13,7 +16,6 @@ module Lanes::Concerns
|
|
13
16
|
belongs_to :created_by, :class_name=>Lanes::User
|
14
17
|
belongs_to :updated_by, :class_name=>Lanes::User
|
15
18
|
|
16
|
-
self.blacklist_attributes :created_at, :updated_at, :created_by_id, :updated_by_id
|
17
19
|
before_update :record_update_modifications
|
18
20
|
before_create :record_create_modifications
|
19
21
|
|
data/lib/lanes/api.rb
CHANGED
data/lib/lanes/api/cable.rb
CHANGED
@@ -7,6 +7,9 @@ module Lanes
|
|
7
7
|
mattr_reader :server
|
8
8
|
mattr_reader :config
|
9
9
|
|
10
|
+
def self.handle_request(request)
|
11
|
+
@@server.call(request.env)
|
12
|
+
end
|
10
13
|
|
11
14
|
class Channel < ActionCable::Channel::Base
|
12
15
|
end
|
@@ -15,9 +18,13 @@ module Lanes
|
|
15
18
|
identified_by :current_user
|
16
19
|
|
17
20
|
def connect
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
+
unless cookies['user_id'] &&
|
22
|
+
self.current_user = Lanes::User
|
23
|
+
.where(id: cookies['user_id']).first
|
24
|
+
Lanes.logger.warn("Rejecting ws connection due to unauthorized access by user_id #{cookies['user_id']}")
|
25
|
+
|
26
|
+
reject_unauthorized_connection
|
27
|
+
end
|
21
28
|
end
|
22
29
|
|
23
30
|
protected
|
@@ -28,6 +35,7 @@ module Lanes
|
|
28
35
|
end
|
29
36
|
|
30
37
|
def self.configure
|
38
|
+
|
31
39
|
require_relative 'updates'
|
32
40
|
@@config = ActionCable::Server::Configuration.new
|
33
41
|
config.logger = Lanes.logger
|
@@ -21,18 +21,22 @@ module Lanes
|
|
21
21
|
|
22
22
|
class ControllerBase
|
23
23
|
|
24
|
-
attr_reader :model, :
|
24
|
+
attr_reader :model, :params, :data
|
25
25
|
include FormattedReply
|
26
26
|
|
27
27
|
def initialize(model, authentication, params, data={})
|
28
|
-
@user = authentication.current_user
|
29
28
|
@model = model
|
30
29
|
@params = params
|
31
30
|
@data = data
|
31
|
+
@authentication = authentication
|
32
32
|
end
|
33
33
|
|
34
34
|
protected
|
35
35
|
|
36
|
+
def current_user
|
37
|
+
@current_user ||= @authentication.current_user
|
38
|
+
end
|
39
|
+
|
36
40
|
def perform_retrieval
|
37
41
|
query = build_query
|
38
42
|
query = add_scopes_to_query(query)
|
@@ -61,7 +65,7 @@ module Lanes
|
|
61
65
|
query = add_access_limits_to_query(query)
|
62
66
|
success = true
|
63
67
|
query.each do | record |
|
64
|
-
if
|
68
|
+
if current_user.can_delete?(record, record.id)
|
65
69
|
success = false unless record.destroy
|
66
70
|
end
|
67
71
|
end
|
@@ -78,8 +82,8 @@ module Lanes
|
|
78
82
|
query.each do | record |
|
79
83
|
record_data = data.detect{ |rd| rd['id'] == record.id }
|
80
84
|
next unless record_data
|
81
|
-
if
|
82
|
-
record.set_attribute_data(record_data,
|
85
|
+
if current_user.can_write?(record, record.id)
|
86
|
+
record.set_attribute_data(record_data, current_user)
|
83
87
|
success = false unless record.save
|
84
88
|
end
|
85
89
|
end
|
@@ -91,7 +95,7 @@ module Lanes
|
|
91
95
|
query = build_query
|
92
96
|
query = add_access_limits_to_query(query)
|
93
97
|
record = query.first!
|
94
|
-
record.set_attribute_data(data,
|
98
|
+
record.set_attribute_data(data, current_user)
|
95
99
|
options = build_reply_options.merge(success: record.save)
|
96
100
|
std_api_reply(:update, record, options)
|
97
101
|
end
|
@@ -135,25 +139,25 @@ module Lanes
|
|
135
139
|
options = {}
|
136
140
|
if include_associations.any?
|
137
141
|
options[:include] = include_associations.each_with_object({}) do |association, includes|
|
138
|
-
includes.merge! build_allowed_associations(association
|
142
|
+
includes.merge! build_allowed_associations(association)
|
139
143
|
end
|
140
144
|
end
|
141
145
|
|
142
146
|
if requested_fields.any?
|
143
|
-
options[:methods] = requested_fields.select{|f| model.has_exported_method?(f,
|
147
|
+
options[:methods] = requested_fields.select{|f| model.has_exported_method?(f, current_user) }
|
144
148
|
end
|
145
149
|
options[:format] = reply_with_array? ? 'array' : 'object'
|
146
150
|
options
|
147
151
|
end
|
148
152
|
|
149
|
-
def build_allowed_associations(association,
|
153
|
+
def build_allowed_associations(association, model_class = self.model)
|
150
154
|
includes = {}
|
151
155
|
if association.is_a?(Hash)
|
152
156
|
association.each do |include_name, sub_associations|
|
153
|
-
if model_class.has_exported_association?(include_name,
|
157
|
+
if model_class.has_exported_association?(include_name, current_user) &&
|
154
158
|
( reflection = model_class.reflect_on_association( include_name.to_sym ) )
|
155
159
|
sub_includes = includes[include_name.to_sym] = {}
|
156
|
-
allowed = build_allowed_associations( sub_associations,
|
160
|
+
allowed = build_allowed_associations( sub_associations, reflection.klass )
|
157
161
|
unless allowed.empty?
|
158
162
|
sub_includes[:include] ||= []
|
159
163
|
sub_includes[:include] << allowed
|
@@ -162,12 +166,12 @@ module Lanes
|
|
162
166
|
end
|
163
167
|
elsif association.is_a?(Array)
|
164
168
|
association.each do | sub_association |
|
165
|
-
if model_class.has_exported_association?(sub_association,
|
166
|
-
includes.merge! build_allowed_associations( sub_association,
|
169
|
+
if model_class.has_exported_association?(sub_association, current_user)
|
170
|
+
includes.merge! build_allowed_associations( sub_association, model_class )
|
167
171
|
end
|
168
172
|
end
|
169
173
|
else
|
170
|
-
includes[ association.to_sym ] = {} if model_class.has_exported_association?(association,
|
174
|
+
includes[ association.to_sym ] = {} if model_class.has_exported_association?(association, current_user)
|
171
175
|
end
|
172
176
|
includes
|
173
177
|
end
|
@@ -176,7 +180,7 @@ module Lanes
|
|
176
180
|
|
177
181
|
def add_access_limits_to_query(query)
|
178
182
|
if model.respond_to?(:access_limits_for_query)
|
179
|
-
query = model.access_limits_for_query(query,
|
183
|
+
query = model.access_limits_for_query(query, current_user, params)
|
180
184
|
else
|
181
185
|
query
|
182
186
|
end
|
@@ -216,11 +220,11 @@ module Lanes
|
|
216
220
|
if desired.is_a?(Hash)
|
217
221
|
nested = {}
|
218
222
|
desired.each do | name, sub_associations |
|
219
|
-
nested[name.to_sym] = sub_associations if model.has_exported_association?(name,
|
223
|
+
nested[name.to_sym] = sub_associations if model.has_exported_association?(name, current_user)
|
220
224
|
end
|
221
225
|
results.push(nested) unless nested.empty?
|
222
226
|
else
|
223
|
-
results.push(desired.to_sym) if model.has_exported_association?(desired,
|
227
|
+
results.push(desired.to_sym) if model.has_exported_association?(desired, current_user)
|
224
228
|
end
|
225
229
|
end
|
226
230
|
query = query.includes(allowed_includes) unless allowed_includes.empty?
|
@@ -242,7 +246,7 @@ module Lanes
|
|
242
246
|
|
243
247
|
def add_scope_to_query(query)
|
244
248
|
query_scopes.each do | name, arg |
|
245
|
-
if model.has_exported_scope?(name,
|
249
|
+
if model.has_exported_scope?(name, current_user)
|
246
250
|
args = [name]
|
247
251
|
args.push( arg ) unless arg.blank?
|
248
252
|
query = query.send( *args )
|
@@ -268,7 +272,7 @@ module Lanes
|
|
268
272
|
def convert_field_to_arel(field)
|
269
273
|
if field.include?('.')
|
270
274
|
(table_name, field_name) = field.split('.')
|
271
|
-
if model.has_exported_join_table?(table_name,
|
275
|
+
if model.has_exported_join_table?(table_name, current_user)
|
272
276
|
Arel::Table.new(table_name)[field_name]
|
273
277
|
else
|
274
278
|
nil
|
@@ -1,10 +1,14 @@
|
|
1
1
|
require_relative "handlers/asset.rb"
|
2
2
|
|
3
|
+
unless Lanes.env.production?
|
4
|
+
require_relative("test_specs")
|
5
|
+
end
|
6
|
+
|
3
7
|
module Lanes
|
4
8
|
API.routes.draw do
|
5
9
|
# WS endpoint must come first
|
6
10
|
get Lanes.config.api_path + '/ws' do
|
7
|
-
API::Cable.
|
11
|
+
API::Cable.handle_request(request)
|
8
12
|
end
|
9
13
|
|
10
14
|
Extensions.each(reversed: true) do | ext |
|
@@ -24,5 +28,9 @@ module Lanes
|
|
24
28
|
API::PubSub.publish("file-change", data)
|
25
29
|
"OK"
|
26
30
|
end
|
31
|
+
|
27
32
|
end
|
33
|
+
|
34
|
+
API.set_root_view :lanes_root_view
|
35
|
+
|
28
36
|
end
|
@@ -34,10 +34,9 @@ module Lanes::API::Handlers
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def self.getter
|
37
|
-
root = Lanes::Extensions.controlling
|
38
|
-
.root_path.join('public', 'files')
|
37
|
+
root = Lanes::Extensions.controlling.root_path.join('public', 'files')
|
39
38
|
lambda do
|
40
|
-
|
39
|
+
send_file(root.join( params['splat'].first ).to_s)
|
41
40
|
end
|
42
41
|
end
|
43
42
|
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
module Lanes
|
2
2
|
module API
|
3
|
-
|
4
3
|
module HelperMethods
|
5
|
-
|
6
4
|
def lanes_application_title
|
7
5
|
Extensions.controlling.title
|
8
6
|
end
|
@@ -16,8 +14,7 @@ module Lanes
|
|
16
14
|
end
|
17
15
|
|
18
16
|
def client_bootstrap_data(mergedWith: {})
|
19
|
-
|
20
|
-
.merge(mergedWith), mode: :compat)
|
17
|
+
API.to_json(Extensions.client_bootstrap_data(self).merge(mergedWith))
|
21
18
|
end
|
22
19
|
|
23
20
|
def csrf_token
|
@@ -30,11 +27,11 @@ module Lanes
|
|
30
27
|
|
31
28
|
def error_as_json
|
32
29
|
Lanes.logger.warn request.env['sinatra.error']
|
33
|
-
|
30
|
+
API.to_json(
|
34
31
|
success: false,
|
35
32
|
errors: { exception: request.env['sinatra.error'].message },
|
36
33
|
message: request.env['sinatra.error'].message
|
37
|
-
|
34
|
+
)
|
38
35
|
end
|
39
36
|
|
40
37
|
def data
|
@@ -45,13 +42,10 @@ module Lanes
|
|
45
42
|
@request_origin ||= env['HTTP_ORIGIN']
|
46
43
|
end
|
47
44
|
|
48
|
-
def json_reply(
|
45
|
+
def json_reply(response)
|
49
46
|
content_type 'application/json'
|
50
|
-
|
47
|
+
API.to_json(response)
|
51
48
|
end
|
52
|
-
|
53
|
-
|
54
49
|
end
|
55
|
-
|
56
50
|
end
|
57
51
|
end
|
data/lib/lanes/api/pub_sub.rb
CHANGED
@@ -5,23 +5,29 @@ module Lanes
|
|
5
5
|
|
6
6
|
class PubSub < Cable::Channel
|
7
7
|
PREFIX = 'ps:'
|
8
|
+
|
8
9
|
def on(data)
|
9
|
-
|
10
|
-
stream_from channel
|
10
|
+
stream_from channel_prefix + data['channel']
|
11
11
|
end
|
12
12
|
|
13
13
|
def off(data)
|
14
|
-
channel =
|
14
|
+
channel = channel_prefix + data['channel']
|
15
15
|
cb = pubsub.instance_variable_get('@listener')
|
16
16
|
.instance_variable_get('@subscribers')[channel].first
|
17
17
|
pubsub.unsubscribe(channel, cb)
|
18
18
|
end
|
19
19
|
|
20
20
|
def self.publish(channel, data)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
channel = channel_prefix + channel
|
22
|
+
ActionCable.server.broadcast(channel, data.merge(channel: channel))
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.channel_prefix
|
26
|
+
PREFIX
|
27
|
+
end
|
28
|
+
|
29
|
+
def channel_prefix
|
30
|
+
PREFIX
|
25
31
|
end
|
26
32
|
|
27
33
|
end
|
@@ -37,7 +37,7 @@ module Lanes
|
|
37
37
|
params[:nested_attribute] = Hash[ options[:parent_attribute],
|
38
38
|
params[parent_attribute] ]
|
39
39
|
end
|
40
|
-
wrap_reply(options.
|
40
|
+
wrap_reply(options.reverse_merge(with_transaction: !request.get?)) do
|
41
41
|
yield controller.new(model, authentication, params, data)
|
42
42
|
end
|
43
43
|
end
|