yeti 0.1.1 → 0.1.2
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/README.md +147 -1
- data/lib/yeti/context.rb +7 -5
- data/lib/yeti/editor.rb +1 -1
- data/lib/yeti/version.rb +1 -1
- data/spec/yeti/context_spec.rb +8 -4
- data/spec/yeti/editor_spec.rb +9 -1
- metadata +4 -4
data/README.md
CHANGED
@@ -20,7 +20,153 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
|
23
|
+
### Yeti::Context
|
24
|
+
|
25
|
+
The context object allows to communicate application state coming from the
|
26
|
+
controllers. First, let's create a Context class tuned to your application
|
27
|
+
logic.
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
class Context < Yeti::Context
|
31
|
+
def initialize(hash)
|
32
|
+
super hash
|
33
|
+
@section = hash.fetch :section
|
34
|
+
end
|
35
|
+
|
36
|
+
def in_admin?
|
37
|
+
section==:admin
|
38
|
+
|
39
|
+
def api_call?
|
40
|
+
section==:api
|
41
|
+
end
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
Typical usage in controller:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
class Admin::BaseController < ApplicationController
|
49
|
+
private
|
50
|
+
def current_context
|
51
|
+
Context.new account_id: session[:account_id, section: :admin
|
52
|
+
end
|
53
|
+
end
|
54
|
+
class Admin::UsersController < Admin::BaseController
|
55
|
+
def index
|
56
|
+
@users = UserSearch.new context, params
|
57
|
+
end
|
58
|
+
|
59
|
+
def show
|
60
|
+
@user = UserViewer.new context, params[:id]
|
61
|
+
end
|
62
|
+
|
63
|
+
def new
|
64
|
+
user
|
65
|
+
end
|
66
|
+
|
67
|
+
def create
|
68
|
+
if user.update_attributes params[:user]
|
69
|
+
redirect_to action: :index, notice: t(:successfully_created)
|
70
|
+
else
|
71
|
+
flash.now[:error] = t(:please_fix_errors_and_retry)
|
72
|
+
render :new
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def edit
|
77
|
+
user
|
78
|
+
end
|
79
|
+
|
80
|
+
def update
|
81
|
+
if user.update_attributes params[:user]
|
82
|
+
redirect_to action: :index, notice: t(:successfully_updated)
|
83
|
+
else
|
84
|
+
flash.now[:error] = t(:please_fix_errors_and_retry)
|
85
|
+
render :edit
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def user
|
90
|
+
@user ||= UserEditor.new context, params[:id]
|
91
|
+
end
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
The presenters can then use the context to restrict search results, change
|
96
|
+
validation, etc. The context object is also useful to track current account in
|
97
|
+
order to apply permissions or know who is performing the action.
|
98
|
+
|
99
|
+
Let's say you have a Account model:
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
class Account < ActiveRecord::Base
|
103
|
+
def guest?
|
104
|
+
false
|
105
|
+
end
|
106
|
+
end
|
107
|
+
```
|
108
|
+
|
109
|
+
of course it could be using Sequel, Mongoid or the ORM of your liking. Then you
|
110
|
+
can define your context class this way:
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
class Context < Yeti::Context
|
114
|
+
class NoAccount < Yeti::Context::NoAccount
|
115
|
+
def guest?
|
116
|
+
true
|
117
|
+
end
|
118
|
+
end
|
119
|
+
delegate :guest?, to: :account
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
def find_account_by_id(id)
|
124
|
+
Account.find_by_id id
|
125
|
+
end
|
126
|
+
|
127
|
+
def no_account
|
128
|
+
NoAccount.new
|
129
|
+
end
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
And with that setup you get:
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
existing_account_id = 1
|
137
|
+
invalid_id = 2
|
138
|
+
Context.new.guest? #=> true
|
139
|
+
Context.new(account_id: existing_account_id).guest? #=> false
|
140
|
+
Context.new(account_id: invalid_id).guest? #=> true
|
141
|
+
```
|
142
|
+
|
143
|
+
No more passing tons of variables from presenters to presenters, the context
|
144
|
+
object regroups and unify this communication while being easy to test in
|
145
|
+
isolation.
|
146
|
+
|
147
|
+
### Yeti::Search
|
148
|
+
|
149
|
+
The search object aims to simplify creating pages with numerous filters.
|
150
|
+
|
151
|
+
Let's say you have the following Sequel model:
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
class User < Sequel::Model
|
155
|
+
end
|
156
|
+
```
|
157
|
+
|
158
|
+
then you can create UserSearch like this:
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
class UserSearch < Yeti::Search
|
162
|
+
private
|
163
|
+
def paginated_results
|
164
|
+
User.search(search).paginate page, per_page
|
165
|
+
end
|
166
|
+
end
|
167
|
+
```
|
168
|
+
|
169
|
+
### Yeti::Editor
|
24
170
|
|
25
171
|
## Contributing
|
26
172
|
|
data/lib/yeti/context.rb
CHANGED
@@ -6,13 +6,15 @@ module Yeti
|
|
6
6
|
|
7
7
|
delegate :id, to: :account, prefix: :account
|
8
8
|
|
9
|
-
def initialize(hash)
|
10
|
-
@
|
9
|
+
def initialize(hash={})
|
10
|
+
@hash = hash
|
11
11
|
end
|
12
12
|
|
13
13
|
def account
|
14
|
-
@account ||=
|
15
|
-
|
14
|
+
@account ||= begin
|
15
|
+
given_account_id = hash[:account_id]
|
16
|
+
(find_account_by_id given_account_id if given_account_id) || no_account
|
17
|
+
end
|
16
18
|
end
|
17
19
|
|
18
20
|
def find_account_by_id(id)
|
@@ -21,7 +23,7 @@ module Yeti
|
|
21
23
|
|
22
24
|
private
|
23
25
|
|
24
|
-
attr_reader :
|
26
|
+
attr_reader :hash
|
25
27
|
|
26
28
|
def no_account
|
27
29
|
NoAccount.new
|
data/lib/yeti/editor.rb
CHANGED
data/lib/yeti/version.rb
CHANGED
data/spec/yeti/context_spec.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Yeti::Context do
|
4
|
-
context "
|
5
|
-
it "
|
6
|
-
|
7
|
-
|
4
|
+
context "without hash" do
|
5
|
+
it "#account is an instance of Yeti::Context::NoAccount" do
|
6
|
+
Yeti::Context.new.account.should be_kind_of Yeti::Context::NoAccount
|
7
|
+
end
|
8
|
+
end
|
9
|
+
context "when account_id is not in hash" do
|
10
|
+
it "#account is an instance of Yeti::Context::NoAccount" do
|
11
|
+
Yeti::Context.new({}).account.should be_kind_of Yeti::Context::NoAccount
|
8
12
|
end
|
9
13
|
end
|
10
14
|
context "when account_id is nil" do
|
data/spec/yeti/editor_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Yeti::Editor do
|
4
4
|
let(:context){ mock :context }
|
5
|
-
subject{ Yeti::Editor.new context
|
5
|
+
subject{ Yeti::Editor.new context }
|
6
6
|
it "keeps given context" do
|
7
7
|
subject.context.should be context
|
8
8
|
end
|
@@ -23,6 +23,14 @@ describe Yeti::Editor do
|
|
23
23
|
subject.edited.should be expected
|
24
24
|
end
|
25
25
|
end
|
26
|
+
context "with id nil" do
|
27
|
+
subject{ Yeti::Editor.new context, nil }
|
28
|
+
it{ should_not be_persisted }
|
29
|
+
it "uses #new_object to initialize main object being edited" do
|
30
|
+
subject.stub(:new_object).and_return(expected = mock)
|
31
|
+
subject.edited.should be expected
|
32
|
+
end
|
33
|
+
end
|
26
34
|
context "without id" do
|
27
35
|
it{ should_not be_persisted }
|
28
36
|
it "uses #new_object to initialize main object being edited" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yeti
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-11-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|
@@ -114,7 +114,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
114
114
|
version: '0'
|
115
115
|
segments:
|
116
116
|
- 0
|
117
|
-
hash:
|
117
|
+
hash: 3542103795249747171
|
118
118
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
119
|
none: false
|
120
120
|
requirements:
|
@@ -123,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
123
|
version: '0'
|
124
124
|
segments:
|
125
125
|
- 0
|
126
|
-
hash:
|
126
|
+
hash: 3542103795249747171
|
127
127
|
requirements: []
|
128
128
|
rubyforge_project:
|
129
129
|
rubygems_version: 1.8.24
|