arcane 0.0.3 → 0.1.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.
- data/.travis.yml +0 -1
- data/CHANGELOG.md +9 -0
- data/README.md +113 -5
- data/lib/arcane.rb +21 -1
- data/lib/arcane/version.rb +1 -1
- data/spec/arcane_spec.rb +14 -0
- metadata +4 -3
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
### Arcane **0.1.0** [head] – 2013-07-11
|
2
|
+
* **[bugfix]** Arcane should no longer error when there is
|
3
|
+
no current_user present.
|
4
|
+
* **[feature]** Added new query syntax for the `refine`
|
5
|
+
helper. It now supports custom params and/or refinery
|
6
|
+
keys to be sent as arguments.
|
7
|
+
|
8
|
+
### Arcane **0.0.3** [current] – 2013-07-11
|
9
|
+
* Initial Release
|
data/README.md
CHANGED
@@ -10,6 +10,114 @@ design patterns to organise and easily harnass the power of strong parameters in
|
|
10
10
|
Arcane magic is real and reliable, no cheap tricks.
|
11
11
|
Inspired by [Pundit](https://github.com/elabs/pundit)
|
12
12
|
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
First of all, include `Arcane` in your controller. This will give you access to the `refine` helper.
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
# app/controllers/application_controller.rb
|
19
|
+
class ApplicationController < ActionController::Base
|
20
|
+
include Arcane
|
21
|
+
end
|
22
|
+
```
|
23
|
+
|
24
|
+
Before you can use the `refine` helper, you need a Refinery for the model you want to pass parameters to.
|
25
|
+
Simply create the directory `/app/refineries` in your Rails project. Create a Refinery your model, in this
|
26
|
+
case Article. `/app/refineries/article_refinery.rb`. Create a class in that file called `ArticleRefinery`.
|
27
|
+
|
28
|
+
Methods defined in the refinery should reflect the controller method for clarity, but can be anything you
|
29
|
+
want it to be. These methods must return an array containing the same parameters you would otherwise send
|
30
|
+
to strong parameters.
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
# app/refineries/article_refinery.rb
|
34
|
+
class ArticleRefinery < Arcane::Refinery
|
35
|
+
def create
|
36
|
+
[:title] + update
|
37
|
+
end
|
38
|
+
def update
|
39
|
+
[:content]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
Next up, using the `refine` helper. The helper can be called from anywhere in your controller and views
|
45
|
+
and accepts one parameter, the object for which you want to *refine* the parameters, then followed by
|
46
|
+
calling the method for what parameters you want.
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
refined_params = refine @article, :create
|
50
|
+
```
|
51
|
+
|
52
|
+
In context of the controller method it might look something like this:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
class ArticlesController < ApplicationController
|
56
|
+
|
57
|
+
def create
|
58
|
+
@article = Article.new(refine(Article,:create))
|
59
|
+
@article.save
|
60
|
+
end
|
61
|
+
|
62
|
+
def update
|
63
|
+
@article = Article.find(params[:id])
|
64
|
+
@article.update_attributes(refine(@article,:update))
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
```
|
70
|
+
|
71
|
+
## Features
|
72
|
+
|
73
|
+
### Custom Parameters
|
74
|
+
Arcane isn't all magic (though mostly). You can pass your own parameters to the `refine` method, without
|
75
|
+
having to worry which order you put them in as long as the permit object is the first one.
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
my_params = { article: { title: "Hello" } }
|
79
|
+
refine(@article,my_params,:create)
|
80
|
+
refine(@article,:update,my_params)
|
81
|
+
```
|
82
|
+
|
83
|
+
### Default Parameters
|
84
|
+
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. **While you should probably never put yourself in this situation**, the feature
|
86
|
+
is available for those edge case scenarios where you need it.
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
class AmbiguityRefinery < Arcane::Refinery
|
90
|
+
def default
|
91
|
+
[:data]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
```
|
95
|
+
|
96
|
+
### Root Requirement
|
97
|
+
You are able to disable or change the root requirement. Let's say you have a sessions endpoint where
|
98
|
+
you don't have your username and password parameters wrapped in a root. Now you can use the root class
|
99
|
+
method and set it to nil or false and it will automatically not require it.
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
class SessionRefinery < Arcane::Refinery
|
103
|
+
def self.root
|
104
|
+
false
|
105
|
+
end
|
106
|
+
end
|
107
|
+
```
|
108
|
+
|
109
|
+
Or if you have a `MeRefinery` for allowing certain parameters on a `/me.json` which is still a user
|
110
|
+
object. You can just set a root class method on your refinery and it will use this to determine if
|
111
|
+
the requirements.
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
class MeRefinery < UserRefinery
|
115
|
+
def self.root
|
116
|
+
:user
|
117
|
+
end
|
118
|
+
end
|
119
|
+
```
|
120
|
+
|
13
121
|
## Requirements
|
14
122
|
|
15
123
|
Currently this gem is only supported for Rails and with any of these ruby versions:
|
@@ -34,13 +142,13 @@ And then execute:
|
|
34
142
|
$ bundle
|
35
143
|
```
|
36
144
|
|
37
|
-
## Features
|
38
|
-
|
39
145
|
## To-do
|
40
146
|
|
41
|
-
|
42
|
-
|
43
|
-
|
147
|
+
- [ ] Write rails generators
|
148
|
+
- [x] List features
|
149
|
+
- [x] Add Documentation
|
150
|
+
- [ ] Add documentation for HATEOAS
|
151
|
+
- [ ] Automatic method detection
|
44
152
|
|
45
153
|
## Contributing
|
46
154
|
|
data/lib/arcane.rb
CHANGED
@@ -22,7 +22,27 @@ module Arcane
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def refine(object,*args)
|
25
|
-
|
25
|
+
|
26
|
+
current_user = nil unless respond_to?(:current_user)
|
27
|
+
|
28
|
+
opts = { }
|
29
|
+
|
30
|
+
args.each do |arg|
|
31
|
+
if [String,Symbol].any? { |c| arg.kind_of?(c) }
|
32
|
+
opts[:method] ||= arg
|
33
|
+
elsif [Hash,HashWithIndifferentAccess,ActionController::Parameters].any? { |c| arg.kind_of?(c) }
|
34
|
+
opts[:params] ||= arg
|
35
|
+
elsif current_user.nil?
|
36
|
+
opts[:user] ||= arg
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
opts[:params] ||= params
|
41
|
+
opts[:user] ||= current_user
|
42
|
+
opts[:object] ||= object.respond_to?(:new) ? object.new : object
|
43
|
+
|
44
|
+
chain = Arcane::Chain.new(opts[:params],opts[:object],opts[:user])
|
45
|
+
return opts[:method].present? ? chain.send(opts[:method]) : chain
|
26
46
|
end
|
27
47
|
|
28
48
|
end
|
data/lib/arcane/version.rb
CHANGED
data/spec/arcane_spec.rb
CHANGED
@@ -19,11 +19,20 @@ describe Arcane do
|
|
19
19
|
}
|
20
20
|
})
|
21
21
|
end
|
22
|
+
let(:custom_params) do
|
23
|
+
HashWithIndifferentAccess.new({
|
24
|
+
article: {
|
25
|
+
tags: ["test","greeting"]
|
26
|
+
}
|
27
|
+
})
|
28
|
+
end
|
22
29
|
|
23
30
|
describe '#refine' do
|
24
31
|
|
25
32
|
it { controller.refine(article).should be_a Arcane::Chain }
|
33
|
+
it { controller.refine(article,:update).should be_a ActionController::Parameters }
|
26
34
|
it { controller.refine(article).update.should be_a ActionController::Parameters }
|
35
|
+
it { controller.refine(Article)._object.should be_a Article }
|
27
36
|
|
28
37
|
it 'filters parameters correctly' do
|
29
38
|
controller.refine(article).update.should eq expected_params(:title,:content)
|
@@ -37,6 +46,11 @@ describe Arcane do
|
|
37
46
|
controller.refine(article).publish.should eq expected_params(:title,:content,:tags)
|
38
47
|
end
|
39
48
|
|
49
|
+
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)
|
52
|
+
end
|
53
|
+
|
40
54
|
end
|
41
55
|
|
42
56
|
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.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -118,6 +118,7 @@ files:
|
|
118
118
|
- .gitignore
|
119
119
|
- .rspec
|
120
120
|
- .travis.yml
|
121
|
+
- CHANGELOG.md
|
121
122
|
- Gemfile
|
122
123
|
- LICENSE.txt
|
123
124
|
- README.md
|
@@ -147,7 +148,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
147
148
|
version: '0'
|
148
149
|
segments:
|
149
150
|
- 0
|
150
|
-
hash:
|
151
|
+
hash: 2536535515859705955
|
151
152
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
153
|
none: false
|
153
154
|
requirements:
|
@@ -156,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
156
157
|
version: '0'
|
157
158
|
segments:
|
158
159
|
- 0
|
159
|
-
hash:
|
160
|
+
hash: 2536535515859705955
|
160
161
|
requirements: []
|
161
162
|
rubyforge_project:
|
162
163
|
rubygems_version: 1.8.25
|