arturo 2.2.0 → 3.0.0
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +46 -0
- data/README.md +141 -91
- data/app/controllers/arturo/features_controller.rb +3 -3
- data/app/helpers/arturo/features_helper.rb +1 -0
- data/app/views/arturo/features/_feature.html.erb +1 -0
- data/app/views/arturo/features/_form.html.erb +1 -0
- data/app/views/arturo/features/edit.html.erb +1 -0
- data/app/views/arturo/features/forbidden.html.erb +1 -0
- data/app/views/arturo/features/index.html.erb +1 -0
- data/app/views/arturo/features/new.html.erb +1 -0
- data/app/views/arturo/features/show.html.erb +1 -0
- data/config/routes.rb +1 -0
- data/lib/arturo/controller_filters.rb +2 -1
- data/lib/arturo/engine.rb +6 -2
- data/lib/arturo/feature.rb +41 -38
- data/lib/arturo/feature_availability.rb +2 -1
- data/lib/arturo/feature_caching.rb +103 -10
- data/lib/arturo/feature_factories.rb +3 -2
- data/lib/arturo/feature_management.rb +1 -0
- data/lib/arturo/feature_params_support.rb +1 -0
- data/lib/arturo/middleware.rb +1 -0
- data/lib/arturo/no_such_feature.rb +1 -0
- data/lib/arturo/null_logger.rb +8 -0
- data/lib/arturo/special_handling.rb +6 -6
- data/lib/arturo/test_support.rb +3 -2
- data/lib/arturo/version.rb +4 -0
- data/lib/arturo.rb +12 -2
- data/lib/generators/arturo/assets_generator.rb +1 -0
- data/lib/generators/arturo/feature_model_generator.rb +14 -0
- data/lib/generators/arturo/initializer_generator.rb +1 -0
- data/lib/generators/arturo/migration_generator.rb +10 -10
- data/lib/generators/arturo/routes_generator.rb +1 -0
- data/lib/generators/arturo/templates/feature.rb +9 -0
- data/lib/generators/arturo/templates/initializer.rb +1 -0
- data/lib/generators/arturo/templates/migration.erb +17 -0
- metadata +50 -118
- data/lib/generators/arturo/templates/migration.rb +0 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 114d46ab7339cbbdd1c2a3a3ec26b030b825d19e34251255ea335e574200da0e
|
|
4
|
+
data.tar.gz: efafe224e924eb3a87f48d7bb7db5b61f77d1446c0bec296c929dcf17dac970b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 258fd4d3264819126bfeaf84acf8ec93cbe28930b09478a061d4c077ac4212cccf78e87762d83532b6ee60652eb1105e48cbd15c4a64d5e0005339fbb6eb4632
|
|
7
|
+
data.tar.gz: 5336f810f255103c809286dd9f1560bc775ff466c6e357e6e5e4b9d384226cfdfd532204a1c2970d6e90796a60f829c5002527e5c052c12d9bae5c6ca375e1b5
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,49 @@
|
|
|
1
|
+
## Unreleased
|
|
2
|
+
|
|
3
|
+
## v3.0.0
|
|
4
|
+
|
|
5
|
+
Converts the Feature model into a mixin that should be used by services via a model generator.
|
|
6
|
+
Brings back the `warm_cache!` method.
|
|
7
|
+
Adds support for Rails 7.1.
|
|
8
|
+
|
|
9
|
+
## v2.8.0
|
|
10
|
+
|
|
11
|
+
Drop support for Ruby 2.6
|
|
12
|
+
|
|
13
|
+
Drop Support for Rails 5.0 & 5.1
|
|
14
|
+
|
|
15
|
+
Add support for Ruby 3.2
|
|
16
|
+
|
|
17
|
+
## v2.7.0
|
|
18
|
+
|
|
19
|
+
Adds ability to register cache update listeners with Arturo::FeatureCaching::AllStrategy that are called when the cache is updated
|
|
20
|
+
|
|
21
|
+
## v2.6.0
|
|
22
|
+
|
|
23
|
+
Add support for Rails 7.0
|
|
24
|
+
|
|
25
|
+
Add support for Ruby 3.0 & 3.1
|
|
26
|
+
|
|
27
|
+
Drop support for Rails 4.2
|
|
28
|
+
|
|
29
|
+
Drop support for Ruby 2.4 & 2.5
|
|
30
|
+
|
|
31
|
+
## v2.5.4
|
|
32
|
+
|
|
33
|
+
Bug fix: Explicitly require rails engine to avoid errors that ::Rails::Engine cannot be found.
|
|
34
|
+
|
|
35
|
+
## v2.5.3
|
|
36
|
+
|
|
37
|
+
Bug fix: Allow using Arturo with ActiveRecord, but without all of Rails.
|
|
38
|
+
|
|
39
|
+
## v2.5.2
|
|
40
|
+
|
|
41
|
+
Drop support for Rails 3.2.
|
|
42
|
+
|
|
43
|
+
Add support for Rails 6.1.
|
|
44
|
+
|
|
45
|
+
Switch CI from Travis to GitHub Actions.
|
|
46
|
+
|
|
1
47
|
## v2.2.0
|
|
2
48
|
|
|
3
49
|
Bug fix: making a feature-update request that fails strict params checks now returns a sensible error instead of throwing an exception
|
data/README.md
CHANGED
|
@@ -2,16 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Arturo provides feature sliders for Rails. It lets you turn features on and off
|
|
4
4
|
just like
|
|
5
|
-
[feature flippers](
|
|
5
|
+
[feature flippers](https://code.flickr.net/2009/12/02/flipping-out/),
|
|
6
6
|
but offers more fine-grained control. It supports deploying features only for
|
|
7
|
-
a given
|
|
7
|
+
a given percentage of your users and whitelisting and blacklisting users based
|
|
8
8
|
on any criteria you can express in Ruby.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
the feature's deployment percentage or change its white- or blacklist
|
|
14
|
-
settings).
|
|
10
|
+
The selection is deterministic. So if a user has a feature on Monday, the
|
|
11
|
+
user will still have it on Tuesday (unless you *decrease* the feature's
|
|
12
|
+
deployment percentage or change its white- or blacklist settings).
|
|
15
13
|
|
|
16
14
|
### A quick example
|
|
17
15
|
|
|
@@ -19,38 +17,44 @@ Trish, a developer is working on a new feature: a live feed of recent postings
|
|
|
19
17
|
in the user's city that shows up in the user's sidebar. First, she uses Arturo's
|
|
20
18
|
view helpers to control who sees the sidebar widget:
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
</
|
|
29
|
-
|
|
20
|
+
```ERB
|
|
21
|
+
<%# in app/views/layout/_sidebar.html.erb: %>
|
|
22
|
+
<% if_feature_enabled(:live_postings) do %>
|
|
23
|
+
<div class='widget'>
|
|
24
|
+
<h3>Recent Postings</h3>
|
|
25
|
+
<ol id='live_postings'>
|
|
26
|
+
</ol>
|
|
27
|
+
</div>
|
|
28
|
+
<% end %>
|
|
29
|
+
```
|
|
30
30
|
|
|
31
31
|
Then Trish writes some Javascript that will poll the server for recent
|
|
32
32
|
postings and put them in the sidebar widget:
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
```js
|
|
35
|
+
// in public/javascript/live_postings.js:
|
|
36
|
+
$(function() {
|
|
37
|
+
var livePostingsList = $('#live_postings');
|
|
38
|
+
if (livePostingsList.length > 0) {
|
|
39
|
+
var updatePostingsList = function() {
|
|
40
|
+
livePostingsList.load('/listings/recent');
|
|
41
|
+
setTimeout(updatePostingsList, 30);
|
|
42
|
+
}
|
|
43
|
+
updatePostingsList();
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
````
|
|
45
47
|
|
|
46
48
|
Trish uses Arturo's Controller filters to control who has access to
|
|
47
49
|
the feature:
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
```Ruby
|
|
52
|
+
# in app/controllers/postings_controller:
|
|
53
|
+
class PostingsController < ApplicationController
|
|
54
|
+
require_feature :live_postings, only: :recent
|
|
55
|
+
# ...
|
|
56
|
+
end
|
|
57
|
+
```
|
|
54
58
|
|
|
55
59
|
Trish then deploys this code to production. Nobody will see the feature yet,
|
|
56
60
|
since it's not on for anyone. (In fact, the feature doesn't yet exist
|
|
@@ -66,18 +70,10 @@ feature and deploy it to all users.
|
|
|
66
70
|
|
|
67
71
|
## Installation
|
|
68
72
|
|
|
69
|
-
### In Rails 3 or 4, with Bundler
|
|
70
73
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
$ gem install arturo --version="~> 1.0"
|
|
76
|
-
|
|
77
|
-
### In Rails 2.3
|
|
78
|
-
|
|
79
|
-
Rails 2.3 is no longer supported and has been archived on the
|
|
80
|
-
[`rails_2_3` branch](http://github.com/jamesarosen/arturo/tree/rails_2_3).
|
|
74
|
+
```Ruby
|
|
75
|
+
gem 'arturo'
|
|
76
|
+
```
|
|
81
77
|
|
|
82
78
|
## Configuration
|
|
83
79
|
|
|
@@ -85,24 +81,34 @@ Rails 2.3 is no longer supported and has been archived on the
|
|
|
85
81
|
|
|
86
82
|
#### Run the generators:
|
|
87
83
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
```
|
|
85
|
+
rails g arturo:migration
|
|
86
|
+
rails g arturo:initializer
|
|
87
|
+
rails g arturo:routes
|
|
88
|
+
rails g arturo:assets
|
|
89
|
+
rails g arturo:feature_model
|
|
90
|
+
```
|
|
92
91
|
|
|
93
92
|
#### Run the migration:
|
|
94
93
|
|
|
95
|
-
|
|
94
|
+
```
|
|
95
|
+
rake db:migrate
|
|
96
|
+
```
|
|
96
97
|
|
|
97
98
|
#### Edit the generated migration as necessary
|
|
98
99
|
|
|
99
100
|
#### Edit the configuration
|
|
100
101
|
|
|
102
|
+
#### Edit the Feature model
|
|
103
|
+
|
|
104
|
+
By default, the generated model `Arturo::Feature` inherits from `ActiveRecord::Base`. However, if you’re using multiple databases your models should inherit from an abstract class that specifies a database connection, not directly from `ActiveRecord::Base`. Update the generated model in `app/models/arturo/feature.rb` to make it use a correct database.
|
|
105
|
+
|
|
101
106
|
##### Initializer
|
|
102
107
|
|
|
103
108
|
Open up the newly-generated `config/initializers/arturo_initializer.rb`.
|
|
104
109
|
There are configuration options for the following:
|
|
105
110
|
|
|
111
|
+
* logging capabilities (see [logging](#logging))
|
|
106
112
|
* the method that determines whether a user has permission to manage features
|
|
107
113
|
(see [admin permissions](#adminpermissions))
|
|
108
114
|
* the method that returns the object that has features
|
|
@@ -113,20 +119,29 @@ There are configuration options for the following:
|
|
|
113
119
|
|
|
114
120
|
##### CSS
|
|
115
121
|
|
|
116
|
-
Open up the newly-generated `public/
|
|
122
|
+
Open up the newly-generated `public/stylesheets/arturo_customizations.css`.
|
|
117
123
|
You can add any overrides you like to the feature configuration page styles
|
|
118
|
-
here. **Do not** edit `public/
|
|
124
|
+
here. **Do not** edit `public/stylesheets/arturo.css` as that file may be
|
|
119
125
|
overwritten in future updates to Arturo.
|
|
120
126
|
|
|
121
127
|
### In other frameworks
|
|
122
128
|
|
|
123
129
|
Arturo is a Rails engine. I want to promote reuse on other frameworks by
|
|
124
130
|
extracting key pieces into mixins, though this isn't done yet. Open an
|
|
125
|
-
[issue](http://github.com/
|
|
131
|
+
[issue](http://github.com/zendesk/arturo/issues) and I'll be happy to
|
|
126
132
|
work with you on support for your favorite framework.
|
|
127
133
|
|
|
128
134
|
## Deep-Dive
|
|
129
135
|
|
|
136
|
+
### <span id='logging'>Logging</span>
|
|
137
|
+
|
|
138
|
+
You can provide a logger in order to inspect Arturo usage.
|
|
139
|
+
A potential implementation for Rails would be:
|
|
140
|
+
|
|
141
|
+
```Ruby
|
|
142
|
+
Arturo.logger = Rails.logger
|
|
143
|
+
```
|
|
144
|
+
|
|
130
145
|
### <span id='adminpermissions'>Admin Permissions</span>
|
|
131
146
|
|
|
132
147
|
`Arturo::FeatureManagement#may_manage_features?` is a method that is run in
|
|
@@ -134,15 +149,19 @@ the context of a Controller or View instance. It should return `true` if
|
|
|
134
149
|
and only if the current user may manage permissions. The default implementation
|
|
135
150
|
is as follows:
|
|
136
151
|
|
|
137
|
-
|
|
152
|
+
```Ruby
|
|
153
|
+
current_user.present? && current_user.admin?
|
|
154
|
+
```
|
|
138
155
|
|
|
139
156
|
You can change the implementation in
|
|
140
157
|
`config/initializers/arturo_initializer.rb`. A reasonable implementation
|
|
141
158
|
might be
|
|
142
159
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
160
|
+
```Ruby
|
|
161
|
+
Arturo.permit_management do
|
|
162
|
+
signed_in? && current_user.can?(:manage_features)
|
|
163
|
+
end
|
|
164
|
+
```
|
|
146
165
|
|
|
147
166
|
### <span id='featurerecipients'>Feature Recipients</span>
|
|
148
167
|
|
|
@@ -163,15 +182,19 @@ The default implementation simply returns `current_user`. Like
|
|
|
163
182
|
in `config/initializers/arturo_initializer.rb`. If you want to deploy features
|
|
164
183
|
on a per-account basis, a reasonable implementation might be
|
|
165
184
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
185
|
+
```Ruby
|
|
186
|
+
Arturo.feature_recipient do
|
|
187
|
+
current_account
|
|
188
|
+
end
|
|
189
|
+
```
|
|
169
190
|
|
|
170
191
|
or
|
|
171
192
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
193
|
+
```Ruby
|
|
194
|
+
Arturo.feature_recipient do
|
|
195
|
+
current_user.account
|
|
196
|
+
end
|
|
197
|
+
```
|
|
175
198
|
|
|
176
199
|
If the block returns `nil`, the feature will be disabled.
|
|
177
200
|
|
|
@@ -182,24 +205,30 @@ will have a feature. For example, if all premium users should have the
|
|
|
182
205
|
`:awesome` feature, place the following in
|
|
183
206
|
`config/initializers/arturo_initializer.rb`:
|
|
184
207
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
208
|
+
```Ruby
|
|
209
|
+
Arturo::Feature.whitelist(:awesome) do |user|
|
|
210
|
+
user.account.premium?
|
|
211
|
+
end
|
|
212
|
+
```
|
|
188
213
|
|
|
189
214
|
If, on the other hand, no users on the free plan should have the
|
|
190
215
|
`:awesome` feature, place the following in
|
|
191
216
|
`config/initializers/arturo_initializer.rb`:
|
|
192
217
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
218
|
+
```Ruby
|
|
219
|
+
Arturo::Feature.blacklist(:awesome) do |user|
|
|
220
|
+
user.account.free?
|
|
221
|
+
end
|
|
222
|
+
```
|
|
196
223
|
|
|
197
224
|
If you want to whitelist or blacklist large groups of features at once, you
|
|
198
225
|
can move the feature argument into the block:
|
|
199
226
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
227
|
+
```Ruby
|
|
228
|
+
Arturo::Feature.whitelist do |feature, user|
|
|
229
|
+
user.account.has?(feature.to_sym)
|
|
230
|
+
end
|
|
231
|
+
```
|
|
203
232
|
|
|
204
233
|
### Feature Conditionals
|
|
205
234
|
|
|
@@ -214,9 +243,11 @@ use a before filter. The following will raise a 403 Forbidden error for
|
|
|
214
243
|
every action within `BookHoldsController` that is invoked by a user who
|
|
215
244
|
does not have the `:hold_book` feature.
|
|
216
245
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
246
|
+
```Ruby
|
|
247
|
+
class BookHoldsController < ApplicationController
|
|
248
|
+
require_feature :hold_book
|
|
249
|
+
end
|
|
250
|
+
```
|
|
220
251
|
|
|
221
252
|
`require_feature` accepts as a second argument a `Hash` that it passes on
|
|
222
253
|
to `before_action`, so you can use `:only` and `:except` to specify exactly
|
|
@@ -229,26 +260,32 @@ check there before falling back on Arturo's forbidden page.
|
|
|
229
260
|
|
|
230
261
|
#### Conditional Evaluation
|
|
231
262
|
|
|
232
|
-
Both controllers and views have access to the `if_feature_enabled
|
|
263
|
+
Both controllers and views have access to the `if_feature_enabled?` and
|
|
233
264
|
`feature_enabled?` methods. The former is used like so:
|
|
234
265
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
266
|
+
```ERB
|
|
267
|
+
<% if_feature_enabled?(:reserve_table) %>
|
|
268
|
+
<%= link_to 'Reserve a table', new_restaurant_reservation_path(:restaurant_id => @restaurant) %>
|
|
269
|
+
<% end %>
|
|
270
|
+
```
|
|
238
271
|
|
|
239
272
|
The latter can be used like so:
|
|
240
273
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
274
|
+
```Ruby
|
|
275
|
+
def widgets_for_sidebar
|
|
276
|
+
widgets = []
|
|
277
|
+
widgets << twitter_widget if feature_enabled?(:twitter_integration)
|
|
278
|
+
...
|
|
279
|
+
widgets
|
|
280
|
+
end
|
|
281
|
+
```
|
|
247
282
|
|
|
248
283
|
#### Rack Middleware
|
|
249
284
|
|
|
250
|
-
|
|
251
|
-
|
|
285
|
+
```Ruby
|
|
286
|
+
require 'arturo'
|
|
287
|
+
use Arturo::Middleware, feature: :my_feature
|
|
288
|
+
```
|
|
252
289
|
|
|
253
290
|
#### Outside a Controller
|
|
254
291
|
|
|
@@ -256,11 +293,15 @@ If you want to check availability outside of a controller or view (really
|
|
|
256
293
|
outside of something that has `Arturo::FeatureAvailability` mixed in), you
|
|
257
294
|
can ask either
|
|
258
295
|
|
|
259
|
-
|
|
296
|
+
```Ruby
|
|
297
|
+
Arturo.feature_enabled_for?(:foo, recipient)
|
|
298
|
+
```
|
|
260
299
|
|
|
261
300
|
or the slightly fancier
|
|
262
301
|
|
|
263
|
-
|
|
302
|
+
```Ruby
|
|
303
|
+
Arturo.foo_enabled_for?(recipient)
|
|
304
|
+
```
|
|
264
305
|
|
|
265
306
|
Both check whether the `foo` feature exists and is enabled for `recipient`.
|
|
266
307
|
|
|
@@ -276,15 +317,24 @@ To enable caching `Feature` lookups, mix `Arturo::FeatureCaching` into
|
|
|
276
317
|
`Arturo::Feature` and set the `cache_ttl`. This is best done in an
|
|
277
318
|
initializer:
|
|
278
319
|
|
|
279
|
-
|
|
280
|
-
|
|
320
|
+
```Ruby
|
|
321
|
+
Arturo::Feature.extend(Arturo::FeatureCaching)
|
|
322
|
+
Arturo::Feature.cache_ttl = 10.minutes
|
|
323
|
+
````
|
|
281
324
|
|
|
282
325
|
You can also warm the cache on startup:
|
|
283
326
|
|
|
284
|
-
|
|
327
|
+
```Ruby
|
|
328
|
+
Arturo::Feature.warm_cache!
|
|
329
|
+
```
|
|
285
330
|
|
|
286
331
|
This will pre-fetch all `Feature`s and put them in the cache.
|
|
287
332
|
|
|
333
|
+
To use the current cache state when you can't fetch updates from origin:
|
|
334
|
+
|
|
335
|
+
```Ruby
|
|
336
|
+
Arturo::Feature.extend_cache_on_failure = true
|
|
337
|
+
```
|
|
288
338
|
|
|
289
339
|
The following is the **intended** support for integration with view caching:
|
|
290
340
|
|
|
@@ -302,6 +352,6 @@ on [Sliders](http://en.wikipedia.org/wiki/Sliders).
|
|
|
302
352
|
|
|
303
353
|
## Quality Metrics
|
|
304
354
|
|
|
305
|
-
[](https://github.com/zendesk/arturo/actions?query=workflow%3ACI)
|
|
306
356
|
|
|
307
|
-
[](https://codeclimate.com/github/zendesk/arturo)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'action_controller'
|
|
2
3
|
require 'arturo/feature_params_support'
|
|
3
4
|
|
|
@@ -13,7 +14,6 @@ module Arturo
|
|
|
13
14
|
include Arturo::FeatureManagement
|
|
14
15
|
include Arturo::FeatureParamsSupport
|
|
15
16
|
|
|
16
|
-
unloadable
|
|
17
17
|
respond_to :html, :json, :xml
|
|
18
18
|
|
|
19
19
|
if respond_to?(:before_action)
|
|
@@ -36,7 +36,7 @@ module Arturo
|
|
|
36
36
|
feature = Arturo::Feature.find_by_id(id)
|
|
37
37
|
if feature.blank?
|
|
38
38
|
errors << t('arturo.features.flash.no_such_feature', :id => id)
|
|
39
|
-
elsif feature.
|
|
39
|
+
elsif feature.update(attributes)
|
|
40
40
|
updated_count += 1
|
|
41
41
|
else
|
|
42
42
|
errors << t('arturo.features.flash.error_updating', :id => id, :errors => feature.errors.full_messages.to_sentence)
|
|
@@ -75,7 +75,7 @@ module Arturo
|
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
def update
|
|
78
|
-
if @feature.
|
|
78
|
+
if @feature.update(feature_params)
|
|
79
79
|
flash[:notice] = t('arturo.features.flash.updated', :name => @feature.to_s)
|
|
80
80
|
redirect_to arturo_engine.feature_path(@feature)
|
|
81
81
|
else
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
<%# frozen_string_literal: true %>
|
|
1
2
|
<tr class='feature' id="feature_<%= feature.id %>">
|
|
2
3
|
<td><code class='ruby symbol'><%= feature.symbol %></code></td>
|
|
3
4
|
<td><%= deployment_percentage_range_and_output_tags("features[#{feature.id}][deployment_percentage]", feature.deployment_percentage) %></td>
|
data/config/routes.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
module Arturo
|
|
2
3
|
|
|
3
4
|
# Adds before filters to controllers for specifying that actions
|
|
@@ -13,7 +14,7 @@ module Arturo
|
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
def on_feature_disabled(feature_name)
|
|
16
|
-
render
|
|
17
|
+
render :plain => 'Forbidden', :status => 403
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
module ClassMethods
|
data/lib/arturo/engine.rb
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'arturo/controller_filters'
|
|
2
3
|
require 'arturo/middleware'
|
|
4
|
+
require 'rails/engine'
|
|
3
5
|
|
|
4
6
|
module Arturo
|
|
5
7
|
class Engine < ::Rails::Engine
|
|
6
8
|
ActiveSupport.on_load(:action_controller) do
|
|
7
9
|
include Arturo::FeatureAvailability
|
|
8
|
-
helper Arturo::FeatureAvailability
|
|
9
10
|
include Arturo::ControllerFilters
|
|
10
|
-
helper
|
|
11
|
+
if respond_to?(:helper)
|
|
12
|
+
helper Arturo::FeatureAvailability
|
|
13
|
+
helper Arturo::FeatureManagement
|
|
14
|
+
end
|
|
11
15
|
end
|
|
12
16
|
|
|
13
17
|
root = File.expand_path("../../..", __FILE__)
|