arcane 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,7 +7,6 @@ rvm:
7
7
  - rbx-19mode
8
8
 
9
9
  env:
10
- - "strong_parameters=0.2.0"
11
10
  - "strong_parameters=0.2.1"
12
11
  - "activesupport=3.2.13"
13
12
  - "activesupport=4.0.0"
@@ -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
- * Write rails generators
42
- * List features
43
- * Add Documentation
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
 
@@ -22,7 +22,27 @@ module Arcane
22
22
  end
23
23
 
24
24
  def refine(object,*args)
25
- Arcane::Chain.new(params,object,current_user)
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
@@ -1,3 +1,3 @@
1
1
  module Arcane
2
- VERSION = "0.0.3"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -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.3
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: 3121159589769937332
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: 3121159589769937332
160
+ hash: 2536535515859705955
160
161
  requirements: []
161
162
  rubyforge_project:
162
163
  rubygems_version: 1.8.25