arcane 0.1.0 → 0.1.1
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.
- data/CHANGELOG.md +7 -2
- data/README.md +49 -8
- data/arcane.gemspec +3 -2
- data/lib/arcane.rb +1 -0
- data/lib/arcane/version.rb +1 -1
- data/spec/arcane_spec.rb +48 -8
- data/spec/spec_helper.rb +14 -1
- metadata +5 -4
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,14 @@
|
|
1
|
-
### Arcane **0.1.
|
1
|
+
### Arcane **0.1.1** [head] – 2013-07-11
|
2
|
+
* **[feature]** The `refine` helper no longer needs a
|
3
|
+
refinery method, it will try and detect which one to
|
4
|
+
use based on parameters.
|
5
|
+
|
6
|
+
### Arcane **0.1.0** [current] – 2013-07-11
|
2
7
|
* **[bugfix]** Arcane should no longer error when there is
|
3
8
|
no current_user present.
|
4
9
|
* **[feature]** Added new query syntax for the `refine`
|
5
10
|
helper. It now supports custom params and/or refinery
|
6
11
|
keys to be sent as arguments.
|
7
12
|
|
8
|
-
### Arcane **0.0.3** [
|
13
|
+
### Arcane **0.0.3** [old] – 2013-07-11
|
9
14
|
* Initial Release
|
data/README.md
CHANGED
@@ -3,16 +3,26 @@
|
|
3
3
|
[](https://travis-ci.org/cloudsdaleapp/arcane)
|
4
4
|
[](http://badge.fury.io/rb/arcane)
|
5
5
|
|
6
|
-
Easy to use parameter
|
7
|
-
Arcane provides you with helpers which guide you in leveraging regular
|
8
|
-
design patterns to organise and easily harnass the power of strong parameters
|
6
|
+
Easy to use parameter management, extending [Strong Parameters](https://github.com/rails/strong_parameters),
|
7
|
+
making them a first class citizen. Arcane provides you with helpers which guide you in leveraging regular
|
8
|
+
Ruby classes and object oriented design patterns to organise and easily harnass the power of strong parameters
|
9
|
+
in Rails 3 and 4.
|
9
10
|
|
10
11
|
Arcane magic is real and reliable, no cheap tricks.
|
11
12
|
Inspired by [Pundit](https://github.com/elabs/pundit)
|
12
13
|
|
13
14
|
## Usage
|
14
15
|
|
15
|
-
|
16
|
+
This is how easy it will be:
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
@article = Article.new refine(Article, :create)
|
20
|
+
```
|
21
|
+
|
22
|
+
### Include the Helper
|
23
|
+
|
24
|
+
Though, we need to do a couple of things before we can get started. First of all include `Arcane` in your
|
25
|
+
controller. This will give you access to the `refine` helper.
|
16
26
|
|
17
27
|
```ruby
|
18
28
|
# app/controllers/application_controller.rb
|
@@ -21,6 +31,8 @@ class ApplicationController < ActionController::Base
|
|
21
31
|
end
|
22
32
|
```
|
23
33
|
|
34
|
+
### Create your first Refinery
|
35
|
+
|
24
36
|
Before you can use the `refine` helper, you need a Refinery for the model you want to pass parameters to.
|
25
37
|
Simply create the directory `/app/refineries` in your Rails project. Create a Refinery your model, in this
|
26
38
|
case Article. `/app/refineries/article_refinery.rb`. Create a class in that file called `ArticleRefinery`.
|
@@ -29,9 +41,13 @@ Methods defined in the refinery should reflect the controller method for clarity
|
|
29
41
|
want it to be. These methods must return an array containing the same parameters you would otherwise send
|
30
42
|
to strong parameters.
|
31
43
|
|
44
|
+
It can be initiated using a `Struct` which accepts an `object` and a `user`. The `refine` method will
|
45
|
+
automatically send `current_user`, if present to the refinery as well as the object you want to apply
|
46
|
+
the parameters on.
|
47
|
+
|
32
48
|
```ruby
|
33
49
|
# app/refineries/article_refinery.rb
|
34
|
-
class ArticleRefinery <
|
50
|
+
class ArticleRefinery < Struct.new(:object,:user)
|
35
51
|
def create
|
36
52
|
[:title] + update
|
37
53
|
end
|
@@ -41,6 +57,15 @@ class ArticleRefinery < Arcane::Refinery
|
|
41
57
|
end
|
42
58
|
```
|
43
59
|
|
60
|
+
**Note**, for convenience sake there is a class called `Arcane::Refinery` which you can use instead of
|
61
|
+
the struct. This class gives you the basic functionality of a refinery for free.
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
class CommentRefinery < Arcane::Refinery; end
|
65
|
+
```
|
66
|
+
|
67
|
+
### Using Arcane in your controller
|
68
|
+
|
44
69
|
Next up, using the `refine` helper. The helper can be called from anywhere in your controller and views
|
45
70
|
and accepts one parameter, the object for which you want to *refine* the parameters, then followed by
|
46
71
|
calling the method for what parameters you want.
|
@@ -80,10 +105,23 @@ having to worry which order you put them in as long as the permit object is the
|
|
80
105
|
refine(@article,:update,my_params)
|
81
106
|
```
|
82
107
|
|
108
|
+
### Automatic Method Detection
|
109
|
+
If you have specified no refinery method in your call to `refine`, Arcane tries to find out for itself
|
110
|
+
what method to use. If you send the params in from a rails controller, Arcane will use the `action` key
|
111
|
+
on the parameters and use your refinery. *If you want to know how to handle fallbacks, see next feature.*
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
class CommentsController < ApplicationController
|
115
|
+
def update
|
116
|
+
@comment = Comment.find(params[:id])
|
117
|
+
@comment.update_attributes refine @comment
|
118
|
+
end
|
119
|
+
end
|
120
|
+
```
|
121
|
+
|
83
122
|
### Default Parameters
|
84
123
|
You are able to specify a `default` method in your refinery which will be prioritized if no the method
|
85
|
-
you call does not exist.
|
86
|
-
is available for those edge case scenarios where you need it.
|
124
|
+
you call does not exist. If default is not specified it will be as the refinery returned an empty array.
|
87
125
|
|
88
126
|
```ruby
|
89
127
|
class AmbiguityRefinery < Arcane::Refinery
|
@@ -144,11 +182,14 @@ $ bundle
|
|
144
182
|
|
145
183
|
## To-do
|
146
184
|
|
185
|
+
- [X] Explain Arcane::Refinery
|
147
186
|
- [ ] Write rails generators
|
148
187
|
- [x] List features
|
149
188
|
- [x] Add Documentation
|
150
189
|
- [ ] Add documentation for HATEOAS
|
151
|
-
- [
|
190
|
+
- [X] Automatic method detection
|
191
|
+
- [ ] RSpec helpers to test Arcane
|
192
|
+
- [ ] Configuration
|
152
193
|
|
153
194
|
## Contributing
|
154
195
|
|
data/arcane.gemspec
CHANGED
@@ -13,7 +13,8 @@ Gem::Specification.new do |gem|
|
|
13
13
|
gem.description = "Parameter filter done OO, extending strong parameters."
|
14
14
|
gem.summary = "Extension for strong_parameters."
|
15
15
|
gem.homepage = "https://github.com/cloudsdaleapp/arcane"
|
16
|
-
|
16
|
+
gem.license = "MIT"
|
17
|
+
|
17
18
|
gem.files = `git ls-files`.split($/)
|
18
19
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
19
20
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
@@ -27,4 +28,4 @@ Gem::Specification.new do |gem|
|
|
27
28
|
gem.add_development_dependency "pry"
|
28
29
|
gem.add_development_dependency "rake"
|
29
30
|
|
30
|
-
end
|
31
|
+
end
|
data/lib/arcane.rb
CHANGED
data/lib/arcane/version.rb
CHANGED
data/spec/arcane_spec.rb
CHANGED
@@ -4,10 +4,10 @@ describe Arcane do
|
|
4
4
|
|
5
5
|
let(:user) { double }
|
6
6
|
let(:article) { Article.new }
|
7
|
+
let(:comment) { Comment.new }
|
7
8
|
let(:controller) { double(:current_user => user, :params => params).tap { |c| c.extend(Arcane) } }
|
8
9
|
let(:params) do
|
9
10
|
HashWithIndifferentAccess.new({
|
10
|
-
action: 'create',
|
11
11
|
article: {
|
12
12
|
title: "hello",
|
13
13
|
content: "world",
|
@@ -34,27 +34,67 @@ describe Arcane do
|
|
34
34
|
it { controller.refine(article).update.should be_a ActionController::Parameters }
|
35
35
|
it { controller.refine(Article)._object.should be_a Article }
|
36
36
|
|
37
|
+
context 'without supplying a refinery method' do
|
38
|
+
|
39
|
+
let(:params) do
|
40
|
+
HashWithIndifferentAccess.new({
|
41
|
+
action: 'create',
|
42
|
+
comment: {
|
43
|
+
content: "Awesome!",
|
44
|
+
score: 5
|
45
|
+
}
|
46
|
+
})
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'still returns a parameters hash' do
|
50
|
+
controller.refine(comment).should be_a ActionController::Parameters
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'finds the right method' do
|
54
|
+
controller.refine(comment).should eq expected_params(:comment,:score,:content)
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'using a missing refinery method' do
|
58
|
+
|
59
|
+
let(:params) do
|
60
|
+
HashWithIndifferentAccess.new({
|
61
|
+
action: 'update',
|
62
|
+
comment: {
|
63
|
+
content: "Awesome!",
|
64
|
+
score: 5
|
65
|
+
}
|
66
|
+
})
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'falls back on default' do
|
70
|
+
controller.refine(comment).should eq expected_params(:comment,:score)
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
37
77
|
it 'filters parameters correctly' do
|
38
|
-
controller.refine(article).update.should eq expected_params(:title,:content)
|
78
|
+
controller.refine(article).update.should eq expected_params(:article,:title,:content)
|
39
79
|
end
|
40
80
|
|
41
81
|
it 'filters nested object parameters correctly' do
|
42
|
-
controller.refine(article).create.should eq expected_params(:title,:content,:links)
|
82
|
+
controller.refine(article).create.should eq expected_params(:article,:title,:content,:links)
|
43
83
|
end
|
44
84
|
|
45
85
|
it 'filters nested scalar parameters correctly' do
|
46
|
-
controller.refine(article).publish.should eq expected_params(:title,:content,:tags)
|
86
|
+
controller.refine(article).publish.should eq expected_params(:article,:title,:content,:tags)
|
47
87
|
end
|
48
88
|
|
49
89
|
it 'filters custom parameters correctly' do
|
50
|
-
controller.refine(article,custom_params,:publish).should eq expected_params(:tags)
|
51
|
-
controller.refine(article,:publish,custom_params).should eq expected_params(:tags)
|
90
|
+
controller.refine(article,custom_params,:publish).should eq expected_params(:article,:tags)
|
91
|
+
controller.refine(article,:publish,custom_params).should eq expected_params(:article,:tags)
|
52
92
|
end
|
53
93
|
|
54
94
|
end
|
55
95
|
|
56
96
|
end
|
57
97
|
|
58
|
-
def expected_params(
|
59
|
-
params[
|
98
|
+
def expected_params(object_name,*includes)
|
99
|
+
params[object_name].reject { |k,_| !includes.include? k.to_sym }
|
60
100
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -33,4 +33,17 @@ class TaskRefinery < Arcane::Refinery
|
|
33
33
|
|
34
34
|
end
|
35
35
|
|
36
|
-
class Shape; end
|
36
|
+
class Shape; end
|
37
|
+
|
38
|
+
class Comment; end
|
39
|
+
class CommentRefinery < Arcane::Refinery
|
40
|
+
|
41
|
+
def create
|
42
|
+
[:content,:score]
|
43
|
+
end
|
44
|
+
|
45
|
+
def default
|
46
|
+
[:score]
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arcane
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -135,7 +135,8 @@ files:
|
|
135
135
|
- spec/arcane_spec.rb
|
136
136
|
- spec/spec_helper.rb
|
137
137
|
homepage: https://github.com/cloudsdaleapp/arcane
|
138
|
-
licenses:
|
138
|
+
licenses:
|
139
|
+
- MIT
|
139
140
|
post_install_message:
|
140
141
|
rdoc_options: []
|
141
142
|
require_paths:
|
@@ -148,7 +149,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
148
149
|
version: '0'
|
149
150
|
segments:
|
150
151
|
- 0
|
151
|
-
hash:
|
152
|
+
hash: 1025235848978620495
|
152
153
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
153
154
|
none: false
|
154
155
|
requirements:
|
@@ -157,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
158
|
version: '0'
|
158
159
|
segments:
|
159
160
|
- 0
|
160
|
-
hash:
|
161
|
+
hash: 1025235848978620495
|
161
162
|
requirements: []
|
162
163
|
rubyforge_project:
|
163
164
|
rubygems_version: 1.8.25
|