magiclabs-userstamp 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/CHANGELOG +26 -0
  2. data/Gemfile +11 -0
  3. data/Gemfile.lock +55 -0
  4. data/LICENSE +20 -0
  5. data/Rakefile +38 -0
  6. data/Readme.rdoc +163 -0
  7. data/VERSION +1 -0
  8. data/init.rb +1 -0
  9. data/lib/migration_helper.rb +19 -0
  10. data/lib/stampable.rb +154 -0
  11. data/lib/stamper.rb +43 -0
  12. data/lib/userstamp.rb +52 -0
  13. data/magiclabs-userstamp.gemspec +85 -0
  14. data/rdoc/classes/Ddb/Controller.html +111 -0
  15. data/rdoc/classes/Ddb/Controller/Userstamp.html +125 -0
  16. data/rdoc/classes/Ddb/Controller/Userstamp/InstanceMethods.html +105 -0
  17. data/rdoc/classes/Ddb/Userstamp.html +121 -0
  18. data/rdoc/classes/Ddb/Userstamp/MigrationHelper.html +111 -0
  19. data/rdoc/classes/Ddb/Userstamp/MigrationHelper/InstanceMethods.html +142 -0
  20. data/rdoc/classes/Ddb/Userstamp/Stampable.html +128 -0
  21. data/rdoc/classes/Ddb/Userstamp/Stampable/ClassMethods.html +225 -0
  22. data/rdoc/classes/Ddb/Userstamp/Stamper.html +112 -0
  23. data/rdoc/classes/Ddb/Userstamp/Stamper/ClassMethods.html +142 -0
  24. data/rdoc/classes/Ddb/Userstamp/Stamper/InstanceMethods.html +207 -0
  25. data/rdoc/classes/Userstamp.html +118 -0
  26. data/rdoc/created.rid +1 -0
  27. data/rdoc/files/CHANGELOG.html +137 -0
  28. data/rdoc/files/LICENSE.html +129 -0
  29. data/rdoc/files/Readme_rdoc.html +301 -0
  30. data/rdoc/files/lib/migration_helper_rb.html +101 -0
  31. data/rdoc/files/lib/stampable_rb.html +101 -0
  32. data/rdoc/files/lib/stamper_rb.html +101 -0
  33. data/rdoc/files/lib/userstamp_rb.html +110 -0
  34. data/rdoc/fr_class_index.html +38 -0
  35. data/rdoc/fr_file_index.html +33 -0
  36. data/rdoc/fr_method_index.html +33 -0
  37. data/rdoc/index.html +24 -0
  38. data/rdoc/rdoc-style.css +208 -0
  39. data/test/compatibility_stamping_test.rb +69 -0
  40. data/test/controllers/posts_controller.rb +26 -0
  41. data/test/controllers/users_controller.rb +12 -0
  42. data/test/controllers/userstamp_controller.rb +9 -0
  43. data/test/helper.rb +61 -0
  44. data/test/models/comment.rb +5 -0
  45. data/test/models/foo.rb +3 -0
  46. data/test/models/person.rb +3 -0
  47. data/test/models/post.rb +13 -0
  48. data/test/models/user.rb +3 -0
  49. data/test/schema.rb +54 -0
  50. data/test/stamping_test.rb +138 -0
  51. data/test/userstamp_controller_test.rb +103 -0
  52. data/test/userstamp_test.rb +7 -0
  53. metadata +105 -0
@@ -0,0 +1,129 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>File: LICENSE</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="fileHeader">
50
+ <h1>LICENSE</h1>
51
+ <table class="header-table">
52
+ <tr class="top-aligned-row">
53
+ <td><strong>Path:</strong></td>
54
+ <td>LICENSE
55
+ </td>
56
+ </tr>
57
+ <tr class="top-aligned-row">
58
+ <td><strong>Last Update:</strong></td>
59
+ <td>Fri Apr 30 22:27:46 +0200 2010</td>
60
+ </tr>
61
+ </table>
62
+ </div>
63
+ <!-- banner header -->
64
+
65
+ <div id="bodyContent">
66
+
67
+
68
+
69
+ <div id="contextContent">
70
+
71
+ <div id="description">
72
+ <p>
73
+ Copyright (c) 2006-2008 DeLynn Berry
74
+ </p>
75
+ <p>
76
+ Permission is hereby granted, free of charge, to any person obtaining a
77
+ copy of this software and associated documentation files (the
78
+ &quot;Software&quot;), to deal in the Software without restriction,
79
+ including without limitation the rights to use, copy, modify, merge,
80
+ publish, distribute, sublicense, and/or sell copies of the Software, and to
81
+ permit persons to whom the Software is furnished to do so, subject to the
82
+ following conditions:
83
+ </p>
84
+ <p>
85
+ The above copyright notice and this permission notice shall be included in
86
+ all copies or substantial portions of the Software.
87
+ </p>
88
+ <p>
89
+ THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,
90
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
91
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
92
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
93
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
94
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
95
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
96
+ </p>
97
+
98
+ </div>
99
+
100
+
101
+ </div>
102
+
103
+
104
+ </div>
105
+
106
+
107
+ <!-- if includes -->
108
+
109
+ <div id="section">
110
+
111
+
112
+
113
+
114
+
115
+
116
+
117
+
118
+ <!-- if method_list -->
119
+
120
+
121
+ </div>
122
+
123
+
124
+ <div id="validator-badges">
125
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
126
+ </div>
127
+
128
+ </body>
129
+ </html>
@@ -0,0 +1,301 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>File: Readme.rdoc</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="fileHeader">
50
+ <h1>Readme.rdoc</h1>
51
+ <table class="header-table">
52
+ <tr class="top-aligned-row">
53
+ <td><strong>Path:</strong></td>
54
+ <td>Readme.rdoc
55
+ </td>
56
+ </tr>
57
+ <tr class="top-aligned-row">
58
+ <td><strong>Last Update:</strong></td>
59
+ <td>Mon Aug 09 21:09:43 +0200 2010</td>
60
+ </tr>
61
+ </table>
62
+ </div>
63
+ <!-- banner header -->
64
+
65
+ <div id="bodyContent">
66
+
67
+
68
+
69
+ <div id="contextContent">
70
+
71
+ <div id="description">
72
+ <p>
73
+ <a href="../classes/Userstamp.html">Userstamp</a>
74
+ </p>
75
+ <h2>Overview</h2>
76
+ <p>
77
+ <a href="../classes/Userstamp.html">Userstamp</a> extends <a
78
+ href="http://api.rubyonrails.com/classes/ActiveRecord/Base.html">ActiveRecord::Base</a>
79
+ to add automatic updating of &#8216;creator&#8217;, &#8216;updater&#8217;,
80
+ and &#8216;deleter&#8217; attributes. It is based loosely on the <a
81
+ href="http://api.rubyonrails.com/classes/ActiveRecord/Timestamp.html">ActiveRecord::Timestamp</a>
82
+ module.
83
+ </p>
84
+ <p>
85
+ Two class methods (<tt>model_stamper</tt> and <tt>stampable</tt>) are
86
+ implemented in this plugin. The <tt>model_stamper</tt> method is used in
87
+ models that are responsible for creating, updating, or deleting other
88
+ objects. The <tt>stampable</tt> method is used in models that are subject
89
+ to being created, updated, or deleted by &#8216;stampers&#8217;.
90
+ </p>
91
+ <h2>Installation</h2>
92
+ <pre>
93
+ - As Rails plugin: `script/plugin install git://github.com/delynn/userstamp.git `
94
+ - As gem: ` sudo gem install userstamp `
95
+ </pre>
96
+ <h2>Usage</h2>
97
+ <p>
98
+ The assumption is that you have two different categories of objects; those
99
+ that manipulate, and those that are manipulated. For those objects that are
100
+ being manipulated there&#8216;s the Stampable module and for the
101
+ manipulators there&#8216;s the Stamper module. There&#8216;s also the
102
+ actual <a href="../classes/Userstamp.html">Userstamp</a> module for your
103
+ controllers that assists in setting up your environment on a per request
104
+ basis.
105
+ </p>
106
+ <h3>Example</h3>
107
+ <p>
108
+ Assume a weblog application has User and Post objects. # 1: Create the
109
+ migrations for these objects
110
+ </p>
111
+ <pre>
112
+ class CreateUsers &lt; ActiveRecord::Migration
113
+ def self.up
114
+ create_table :users, :force =&gt; true do |t|
115
+ ...
116
+ t.userstamps # use t.userstamps(true) if you also want 'deleter_id'
117
+ end
118
+ end
119
+
120
+ def self.down
121
+ drop_table :users
122
+ end
123
+ end
124
+
125
+ class CreatePosts &lt; ActiveRecord::Migration
126
+ def self.up
127
+ create_table :posts, :force =&gt; true do |t|
128
+ ...
129
+ t.userstamps # use t.userstamps(true) if you also want 'deleter_id'
130
+ end
131
+ end
132
+
133
+ def self.down
134
+ drop_table :posts
135
+ end
136
+ end
137
+ </pre>
138
+ <p>
139
+ # 2: Users are going to manipulate Post&#8216;s, use the
140
+ <tt>model_stamper</tt>:
141
+ </p>
142
+ <pre>
143
+ class User &lt; ActiveRecord::Base
144
+ model_stamper
145
+ end
146
+ </pre>
147
+ <p>
148
+ # 3: Set the current user in the ApplicationController:
149
+ </p>
150
+ <pre>
151
+ class ApplicationController &lt; ActionController::Base
152
+ include Userstamp
153
+ end
154
+ </pre>
155
+ <p>
156
+ If all you are interested in is making sure all tables that have the proper
157
+ columns are stamped by the currently logged in user you can stop right
158
+ here. More than likely you want all your associations setup on your stamped
159
+ objects, and that&#8216;s where the <tt>stampable</tt> class method comes
160
+ in. So in our example we&#8216;ll want to use this method in both our User
161
+ and Post classes:
162
+ </p>
163
+ <pre>
164
+ class User &lt; ActiveRecord::Base
165
+ model_stamper
166
+ stampable
167
+ end
168
+
169
+ class Post &lt; ActiveRecord::Base
170
+ stampable
171
+ end
172
+ </pre>
173
+ <p>
174
+ Okay, so what all have we done? The <tt>model_stamper</tt> class method
175
+ injects two methods into the User class. They are stamper= and stamper and
176
+ look like this:
177
+ </p>
178
+ <pre>
179
+ def stamper=(object)
180
+ object_stamper = if object.is_a?(ActiveRecord::Base)
181
+ object.send(&quot;#{object.class.primary_key}&quot;.to_sym)
182
+ else
183
+ object
184
+ end
185
+
186
+ Thread.current[&quot;#{self.to_s.downcase}_#{self.object_id}_stamper&quot;] = object_stamper
187
+ end
188
+
189
+ def stamper
190
+ Thread.current[&quot;#{self.to_s.downcase}_#{self.object_id}_stamper&quot;]
191
+ end
192
+ </pre>
193
+ <p>
194
+ The <tt>stampable</tt> method allows you to customize what columns will get
195
+ stamped, and also creates the <tt>creator</tt>, <tt>updater</tt>, and
196
+ <tt>deleter</tt> associations.
197
+ </p>
198
+ <p>
199
+ The <a href="../classes/Userstamp.html">Userstamp</a> module that we
200
+ included into our ApplicationController uses the setter method to set which
201
+ user is currently making the request. By default the
202
+ &#8216;set_stampers&#8217; method works perfectly with the <a
203
+ href="http://svn.techno-weenie.net/projects/plugins/restful_authentication">RestfulAuthentication</a>
204
+ plug-in:
205
+ </p>
206
+ <pre>
207
+ def set_stampers
208
+ User.stamper = self.current_user
209
+ end
210
+ </pre>
211
+ <p>
212
+ If you aren&#8216;t using ActsAsAuthenticated, then you need to create your
213
+ own version of the <tt>set_stampers</tt> method in the controller where
214
+ you&#8216;ve included the <a href="../classes/Userstamp.html">Userstamp</a>
215
+ module.
216
+ </p>
217
+ <p>
218
+ Now, let&#8216;s get back to the Stampable module (since it really is the
219
+ interesting one). The Stampable module sets up before_* filters that are
220
+ responsible for setting those attributes at the appropriate times. It also
221
+ creates the belongs_to relationships for you.
222
+ </p>
223
+ <p>
224
+ If you need to customize the columns that are stamped, the
225
+ <tt>stampable</tt> method can be completely customized. Here&#8216;s an
226
+ quick example:
227
+ </p>
228
+ <pre>
229
+ class Post &lt; ActiveRecord::Base
230
+ stampable :stamper_class_name =&gt; :person,
231
+ :creator_attribute =&gt; :create_user,
232
+ :updater_attribute =&gt; :update_user,
233
+ :deleter_attribute =&gt; :delete_user
234
+ end
235
+ </pre>
236
+ <h2>Upgrade from 1.x</h2>
237
+ <pre>
238
+ # config/environment.rb
239
+ Ddb::Userstamp.compatibility_mode = true
240
+ </pre>
241
+ <p>
242
+ <a href="http://github.com/delynn/userstamp_sample">Example userstamp
243
+ application</a>
244
+ </p>
245
+ <h2>Running Unit Tests</h2>
246
+ <pre>
247
+ All: rake
248
+ One: ruby test/compatibility_stamping_test.rb
249
+ </pre>
250
+ <h2>Author</h2>
251
+ <p>
252
+ <a href="http://delynnberry.com/">DeLynn Berry</a>
253
+ </p>
254
+ <p>
255
+ The original idea for this plugin came from the Rails Wiki article entitled
256
+ <a
257
+ href="http://wiki.rubyonrails.com/rails/pages/ExtendingActiveRecordExample">Extending
258
+ ActiveRecord</a>.
259
+ </p>
260
+ <h2>Contributors / maintenance / enhancement</h2>
261
+ <ul>
262
+ <li><a href="http://pragmatig.com">Michael Grosser</a>
263
+
264
+ </li>
265
+ <li><a href="http://blog.spovich.com/">John Dell</a>
266
+
267
+ </li>
268
+ </ul>
269
+
270
+ </div>
271
+
272
+
273
+ </div>
274
+
275
+
276
+ </div>
277
+
278
+
279
+ <!-- if includes -->
280
+
281
+ <div id="section">
282
+
283
+
284
+
285
+
286
+
287
+
288
+
289
+
290
+ <!-- if method_list -->
291
+
292
+
293
+ </div>
294
+
295
+
296
+ <div id="validator-badges">
297
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
298
+ </div>
299
+
300
+ </body>
301
+ </html>
@@ -0,0 +1,101 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>File: migration_helper.rb</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="fileHeader">
50
+ <h1>migration_helper.rb</h1>
51
+ <table class="header-table">
52
+ <tr class="top-aligned-row">
53
+ <td><strong>Path:</strong></td>
54
+ <td>lib/migration_helper.rb
55
+ </td>
56
+ </tr>
57
+ <tr class="top-aligned-row">
58
+ <td><strong>Last Update:</strong></td>
59
+ <td>Mon Aug 09 20:17:35 +0200 2010</td>
60
+ </tr>
61
+ </table>
62
+ </div>
63
+ <!-- banner header -->
64
+
65
+ <div id="bodyContent">
66
+
67
+
68
+
69
+ <div id="contextContent">
70
+
71
+
72
+
73
+ </div>
74
+
75
+
76
+ </div>
77
+
78
+
79
+ <!-- if includes -->
80
+
81
+ <div id="section">
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+ <!-- if method_list -->
91
+
92
+
93
+ </div>
94
+
95
+
96
+ <div id="validator-badges">
97
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
98
+ </div>
99
+
100
+ </body>
101
+ </html>