originator 3.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.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +31 -0
  3. data/Gemfile +8 -0
  4. data/LICENSE +20 -0
  5. data/Rakefile +30 -0
  6. data/Readme.rdoc +162 -0
  7. data/VERSION +1 -0
  8. data/lib/migration_helper.rb +19 -0
  9. data/lib/stampable.rb +152 -0
  10. data/lib/stamper.rb +43 -0
  11. data/lib/userstamp.rb +52 -0
  12. data/originator.gemspec +84 -0
  13. data/rdoc/classes/Ddb/Controller.html +111 -0
  14. data/rdoc/classes/Ddb/Controller/Userstamp.html +125 -0
  15. data/rdoc/classes/Ddb/Controller/Userstamp/InstanceMethods.html +105 -0
  16. data/rdoc/classes/Ddb/Userstamp.html +121 -0
  17. data/rdoc/classes/Ddb/Userstamp/MigrationHelper.html +111 -0
  18. data/rdoc/classes/Ddb/Userstamp/MigrationHelper/InstanceMethods.html +142 -0
  19. data/rdoc/classes/Ddb/Userstamp/Stampable.html +128 -0
  20. data/rdoc/classes/Ddb/Userstamp/Stampable/ClassMethods.html +225 -0
  21. data/rdoc/classes/Ddb/Userstamp/Stamper.html +112 -0
  22. data/rdoc/classes/Ddb/Userstamp/Stamper/ClassMethods.html +142 -0
  23. data/rdoc/classes/Ddb/Userstamp/Stamper/InstanceMethods.html +207 -0
  24. data/rdoc/classes/Userstamp.html +118 -0
  25. data/rdoc/created.rid +1 -0
  26. data/rdoc/files/CHANGELOG.html +137 -0
  27. data/rdoc/files/LICENSE.html +129 -0
  28. data/rdoc/files/Readme_rdoc.html +301 -0
  29. data/rdoc/files/lib/migration_helper_rb.html +101 -0
  30. data/rdoc/files/lib/stampable_rb.html +101 -0
  31. data/rdoc/files/lib/stamper_rb.html +101 -0
  32. data/rdoc/files/lib/userstamp_rb.html +110 -0
  33. data/rdoc/fr_class_index.html +38 -0
  34. data/rdoc/fr_file_index.html +33 -0
  35. data/rdoc/fr_method_index.html +33 -0
  36. data/rdoc/index.html +24 -0
  37. data/rdoc/rdoc-style.css +208 -0
  38. data/test/compatibility_stamping_test.rb +69 -0
  39. data/test/controllers/posts_controller.rb +26 -0
  40. data/test/controllers/users_controller.rb +12 -0
  41. data/test/controllers/userstamp_controller.rb +9 -0
  42. data/test/helper.rb +61 -0
  43. data/test/models/comment.rb +5 -0
  44. data/test/models/foo.rb +3 -0
  45. data/test/models/person.rb +3 -0
  46. data/test/models/post.rb +13 -0
  47. data/test/models/user.rb +3 -0
  48. data/test/schema.rb +54 -0
  49. data/test/stamping_test.rb +138 -0
  50. data/test/userstamp_controller_test.rb +103 -0
  51. data/test/userstamp_test.rb +7 -0
  52. metadata +138 -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>