active-record-binder 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/README.md +217 -0
  2. data/bin/arb +13 -0
  3. data/doc/Binder.html +150 -0
  4. data/doc/Binder/AR.html +1880 -0
  5. data/doc/Binder/Command.html +252 -0
  6. data/doc/Binder/Help.html +374 -0
  7. data/doc/Binder/Migrate.html +682 -0
  8. data/doc/Binder/Strategy.html +550 -0
  9. data/doc/Binder/Version.html +285 -0
  10. data/doc/Class.html +220 -0
  11. data/doc/CommandParser.html +268 -0
  12. data/doc/CommandParser/ParseError.html +123 -0
  13. data/doc/DeferedDelegator.html +414 -0
  14. data/doc/MigrationProcessError.html +123 -0
  15. data/doc/MigrationVersionError.html +123 -0
  16. data/doc/String.html +245 -0
  17. data/doc/_index.html +256 -0
  18. data/doc/class_list.html +53 -0
  19. data/doc/css/common.css +1 -0
  20. data/doc/css/full_list.css +57 -0
  21. data/doc/css/style.css +328 -0
  22. data/doc/file.README.html +300 -0
  23. data/doc/file_list.html +55 -0
  24. data/doc/frames.html +28 -0
  25. data/doc/index.html +300 -0
  26. data/doc/js/app.js +214 -0
  27. data/doc/js/full_list.js +173 -0
  28. data/doc/js/jquery.js +4 -0
  29. data/doc/method_list.html +348 -0
  30. data/doc/top-level-namespace.html +114 -0
  31. data/extras/cli_help.png +0 -0
  32. data/lib/active_record_binder.rb +21 -37
  33. data/lib/cli/command.rb +101 -0
  34. data/lib/cli/command_parser.rb +29 -0
  35. data/lib/cli/commands/commands.rb +4 -0
  36. data/lib/cli/commands/help.rb +35 -0
  37. data/lib/cli/commands/migrate.rb +77 -0
  38. data/lib/cli/commands/version.rb +16 -0
  39. data/lib/cli/core_ext.rb +21 -0
  40. data/lib/defered_delegator.rb +69 -0
  41. data/lib/version.rb +3 -0
  42. data/test/active_record_binder_test.rb +262 -0
  43. data/test/foo.sqlite3 +0 -0
  44. data/test/migrations.rb +29 -0
  45. data/test/minitest_helper.rb +15 -0
  46. data/test/mocks.rb +24 -0
  47. metadata +62 -5
@@ -0,0 +1,300 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII" />
6
+ <title>
7
+ File: README
8
+
9
+ &mdash; Documentation by YARD 0.8.4.1
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="css/style.css" type="text/css" media="screen" charset="utf-8" />
14
+
15
+ <link rel="stylesheet" href="css/common.css" type="text/css" media="screen" charset="utf-8" />
16
+
17
+ <script type="text/javascript" charset="utf-8">
18
+ hasFrames = window.top.frames.main ? true : false;
19
+ relpath = '';
20
+ framesUrl = "frames.html#!" + escape(window.location.href);
21
+ </script>
22
+
23
+
24
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
25
+
26
+ <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
27
+
28
+
29
+ </head>
30
+ <body>
31
+ <div id="header">
32
+ <div id="menu">
33
+
34
+ <a href="_index.html">Index</a> &raquo;
35
+ <span class="title">File: README</span>
36
+
37
+
38
+ <div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
39
+ </div>
40
+
41
+ <div id="search">
42
+
43
+ <a class="full_list_link" id="class_list_link"
44
+ href="class_list.html">
45
+ Class List
46
+ </a>
47
+
48
+ <a class="full_list_link" id="method_list_link"
49
+ href="method_list.html">
50
+ Method List
51
+ </a>
52
+
53
+ <a class="full_list_link" id="file_list_link"
54
+ href="file_list.html">
55
+ File List
56
+ </a>
57
+
58
+ </div>
59
+ <div class="clear"></div>
60
+ </div>
61
+
62
+ <iframe id="search_frame"></iframe>
63
+
64
+ <div id="content"><div id='filecontents'><h1><a href="https://rubygems.org/gems/active-record-binder">ActiveRecordBinder</a></h1>
65
+
66
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_arb'>arb</span> <span class='op'>-</span><span class='id identifier rubyid_v'>v</span>
67
+ <span class='comment'># =&gt; 1.2.0
68
+ </span>
69
+ <span class='id identifier rubyid_arb'>arb</span> <span class='op'>-</span><span class='op'>-</span><span class='id identifier rubyid_changelog'>changelog</span>
70
+ <span class='comment'># V 1.2.0 : Bug fixes, refactoring and introduction of the new command-line-tool : `arb`
71
+ </span><span class='comment'># V 1.1.0 : Introducing delegation for ActiveRecord::Base relation methods.
72
+ </span><span class='comment'># V 1.0.1 : Minor fixes and Documentation creation.
73
+ </span><span class='comment'># V 1.0.0 : Release
74
+ </span><span class='comment'>#
75
+ </span></code></pre>
76
+
77
+ <p>A Ruby library for an easier interfacing with ActiveRecord. And an easier way to create elegant migrations.</p>
78
+
79
+ <h1>Installation</h1>
80
+
81
+ <p><code>gem install active-record-binder</code></p>
82
+
83
+ <h1>Why Binder ? What the frak is this ?</h1>
84
+
85
+ <p>I needed a tool to ease the creation of little Plugs and Adapters for ActiveRecord.</p>
86
+
87
+ <p>The idea is that you Bind a class to ActiveRecord by subclassing it with Binder::AR.
88
+ You can specify your own methods and delegate to ActiveRecord whenever you need.</p>
89
+
90
+ <p>It&#39;s kind of a Proxy on steroids, that will do a lot for you.</p>
91
+
92
+ <h2>Show me !</h2>
93
+
94
+ <p>You want to create a Plug for your sqlite database :</p>
95
+
96
+ <pre class="code ruby"><code class="ruby"> <span class='kw'>class</span> <span class='const'>SqlitePlug</span> <span class='op'>&lt;</span> <span class='const'>Binder</span><span class='op'>::</span><span class='const'>AR</span>
97
+ <span class='kw'>end</span>
98
+ </code></pre>
99
+
100
+ <p>Those lines will create a new <code>MySqlPlug</code>, and it will connect to the database specified by your <code>ENV[&#39;APP_DB&#39;]</code>.
101
+ Also, the database adapter defaults to <code>:sqlite3</code>.</p>
102
+
103
+ <p>Now. All this is fine. But you want more :
104
+ * You want to select a precise database without using <code>ENV[&#39;APP_DB&#39;]</code>;
105
+ * Your application uses MySQL.</p>
106
+
107
+ <pre class="code ruby"><code class="ruby"> <span class='kw'>class</span> <span class='const'>MySqlPlug</span> <span class='op'>&lt;</span> <span class='const'>Binder</span><span class='op'>::</span><span class='const'>AR</span>
108
+ <span class='id identifier rubyid_database'>database</span> <span class='symbol'>:db</span>
109
+ <span class='id identifier rubyid_adapter'>adapter</span> <span class='symbol'>:mysql</span>
110
+ <span class='id identifier rubyid_connect_with'>connect_with</span> <span class='label'>user:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>Foo</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>password:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>Bar</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>host:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>localhost</span><span class='tstring_end'>'</span></span>
111
+ <span class='kw'>end</span>
112
+ </code></pre>
113
+
114
+ <p>As you can see : you can specify a database or an adapter by passing a <code>Symbol</code> or a <code>String</code> to both the
115
+ * <code>database()</code> and the
116
+ * <code>adapter()</code> methods.</p>
117
+
118
+ <p>The <code>connect_with()</code> method can be used to pass a <code>Hash</code> of options to the <code>ActiveRecord::Base.establish_connexion()</code> call.</p>
119
+
120
+ <p><em>Please notice that all your instances of MySqlPlug will use those values once defined this way.</em></p>
121
+
122
+ <h2>How do we use this ?</h2>
123
+
124
+ <pre class="code ruby"><code class="ruby"> <span class='kw'>class</span> <span class='const'>MySqlPlug</span> <span class='op'>&lt;</span> <span class='const'>Binder</span><span class='op'>::</span><span class='const'>AR</span>
125
+ <span class='id identifier rubyid_database'>database</span> <span class='symbol'>:db</span>
126
+ <span class='id identifier rubyid_adapter'>adapter</span> <span class='symbol'>:mysql</span>
127
+ <span class='id identifier rubyid_connect_with'>connect_with</span> <span class='label'>user:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>Foo</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>password:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>Bar</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>host:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>localhost</span><span class='tstring_end'>'</span></span>
128
+
129
+ <span class='kw'>def</span> <span class='id identifier rubyid_find'>find</span> <span class='id identifier rubyid_args'>args</span>
130
+ <span class='comment'># But you could use a delegator
131
+ </span> <span class='id identifier rubyid_table'>table</span><span class='period'>.</span><span class='id identifier rubyid_find'>find</span> <span class='id identifier rubyid_args'>args</span>
132
+ <span class='kw'>end</span>
133
+ <span class='kw'>end</span>
134
+
135
+ <span class='comment'># A Model
136
+ </span> <span class='kw'>class</span> <span class='const'>Foo</span>
137
+ <span class='kw'>def</span> <span class='id identifier rubyid_initialize'>initialize</span>
138
+ <span class='comment'># Will bind this instance of the MySqlPlug to the `foos` table
139
+ </span> <span class='ivar'>@plug</span> <span class='op'>=</span> <span class='const'>MySqlPlug</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='symbol'>:foo</span>
140
+ <span class='kw'>end</span>
141
+
142
+ <span class='kw'>def</span> <span class='id identifier rubyid_find'>find</span>
143
+ <span class='comment'># But you could use a delegator
144
+ </span> <span class='ivar'>@plug</span><span class='period'>.</span><span class='id identifier rubyid_find'>find</span>
145
+ <span class='kw'>end</span>
146
+ <span class='kw'>end</span>
147
+ </code></pre>
148
+
149
+ <p><strong>Note :</strong> You can use the <code>table</code> method on any instance of your Plug to get the table class (An ActiveRecord Class Object).</p>
150
+
151
+ <pre class="code ruby"><code class="ruby"> <span class='ivar'>@plug</span> <span class='op'>=</span> <span class='const'>MySqlPlug</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='symbol'>:foo</span>
152
+ <span class='id identifier rubyid_table'>table</span> <span class='op'>=</span> <span class='ivar'>@plug</span><span class='period'>.</span><span class='id identifier rubyid_table'>table</span>
153
+ <span class='comment'># =&gt; MySqlPlug::Foo
154
+ </span> <span class='id identifier rubyid_table'>table</span><span class='period'>.</span><span class='id identifier rubyid_find'>find</span> <span class='comment'># ActiveRecord method call.
155
+ </span> <span class='comment'># =&gt; [&lt;FooObject#1&gt;, &lt;FooObject#2, ...]
156
+ </span></code></pre>
157
+
158
+ <p>Notice how neatly namespaced is the ActiveRecord table class. This way we won&#39;t step over our <code>Foo</code> model.</p>
159
+
160
+ <h1>Relations</h1>
161
+
162
+ <p>If it pleases you, you can create your relations directly in the Binder class. Those methods call are delegated to the underlying table model when initiated.</p>
163
+
164
+ <pre class="code ruby"><code class="ruby"> <span class='kw'>class</span> <span class='const'>FooBinder</span> <span class='op'>&lt;</span> <span class='const'>Binder</span><span class='op'>::</span><span class='const'>AR</span>
165
+ <span class='id identifier rubyid_has_one'>has_one</span> <span class='symbol'>:bar</span>
166
+ <span class='kw'>end</span>
167
+ <span class='kw'>class</span> <span class='const'>BarBinder</span> <span class='op'>&lt;</span> <span class='const'>Binder</span><span class='op'>::</span><span class='const'>AR</span>
168
+ <span class='id identifier rubyid_belongs_to'>belongs_to</span> <span class='symbol'>:foo</span>
169
+ <span class='kw'>end</span>
170
+
171
+ <span class='comment'># And (if the table are accordingly populated, see &quot;The Migration System&quot;, below) :
172
+ </span> <span class='id identifier rubyid_foo'>foo</span> <span class='op'>=</span> <span class='const'>FooBinder</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='lparen'>(</span><span class='symbol'>:foo</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_table'>table</span>
173
+ <span class='id identifier rubyid_foo'>foo</span><span class='period'>.</span><span class='id identifier rubyid_first'>first</span><span class='period'>.</span><span class='id identifier rubyid_bar'>bar</span> <span class='comment'># =&gt; &lt;BarObject&gt;
174
+ </span></code></pre>
175
+
176
+ <p>Delegated methods are the following : <code>has_many</code>, <code>has_one</code>, <code>has_and_belongs_to_many</code>, <code>belongs_to</code>.</p>
177
+
178
+ <h1>The Migration System</h1>
179
+
180
+ <p>I&#39;ve always found the ActiveRecord::Migration system a bit of a pain to use.</p>
181
+
182
+ <p>Therefore, I took the liberty of using pieces of <a href="https://github.com/camping/camping/"><code>_Why&#39;s Camping Web Framework&#39;s</code></a> migration system.
183
+ You can now create your migrations this way :</p>
184
+
185
+ <pre class="code ruby"><code class="ruby"> <span class='kw'>class</span> <span class='const'>CreateFooTable</span> <span class='op'>&lt;</span> <span class='const'>MySqlPlug</span><span class='op'>::</span><span class='const'>Version</span> <span class='float'>1.0</span>
186
+ <span class='kw'>def</span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_up'>up</span>
187
+ <span class='id identifier rubyid_create_table'>create_table</span> <span class='symbol'>:foos</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_t'>t</span><span class='op'>|</span>
188
+ <span class='id identifier rubyid_t'>t</span><span class='period'>.</span><span class='id identifier rubyid_string'>string</span> <span class='symbol'>:name</span>
189
+ <span class='id identifier rubyid_t'>t</span><span class='period'>.</span><span class='id identifier rubyid_timestamps'>timestamps</span>
190
+ <span class='kw'>end</span>
191
+ <span class='kw'>end</span>
192
+
193
+ <span class='kw'>def</span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_down'>down</span>
194
+ <span class='id identifier rubyid_drop_table'>drop_table</span> <span class='symbol'>:foos</span>
195
+ <span class='kw'>end</span>
196
+ <span class='kw'>end</span>
197
+
198
+ <span class='kw'>class</span> <span class='const'>CreateBarTable</span> <span class='op'>&lt;</span> <span class='const'>MySqlPlug</span><span class='op'>::</span><span class='const'>Version</span> <span class='float'>1.1</span>
199
+ <span class='kw'>def</span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_up'>up</span>
200
+ <span class='id identifier rubyid_create_table'>create_table</span> <span class='symbol'>:bars</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_t'>t</span><span class='op'>|</span>
201
+ <span class='id identifier rubyid_t'>t</span><span class='period'>.</span><span class='id identifier rubyid_string'>string</span> <span class='symbol'>:title</span>
202
+ <span class='id identifier rubyid_t'>t</span><span class='period'>.</span><span class='id identifier rubyid_timestamps'>timestamps</span>
203
+ <span class='kw'>end</span>
204
+ <span class='kw'>end</span>
205
+
206
+ <span class='kw'>def</span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_down'>down</span>
207
+ <span class='id identifier rubyid_drop_table'>drop_table</span> <span class='symbol'>:bars</span>
208
+ <span class='kw'>end</span>
209
+ <span class='kw'>end</span>
210
+
211
+ <span class='comment'># You can get the migration version for a pecular migration class.
212
+ </span> <span class='const'>CreateFooTable</span><span class='period'>.</span><span class='id identifier rubyid_version'>version</span> <span class='comment'># =&gt; 1.0
213
+ </span> <span class='const'>CreateBarTable</span><span class='period'>.</span><span class='id identifier rubyid_version'>version</span> <span class='comment'># =&gt; 1.1
214
+ </span></code></pre>
215
+
216
+ <p>Isn&#39;t it neat ?.</p>
217
+
218
+ <p>Now, boy : just use the <code>migrate</code> method to execute your migrations.</p>
219
+
220
+ <pre class="code ruby"><code class="ruby"> <span class='const'>MySqlPlug</span><span class='period'>.</span><span class='id identifier rubyid_migrate'>migrate</span>
221
+ <span class='comment'># =&gt; 1.1
222
+ </span></code></pre>
223
+
224
+ <p>This executes everything up to the latest migration.
225
+ But <code>migrate()</code> can also take a version number as an argument.</p>
226
+
227
+ <pre class="code ruby"><code class="ruby"> <span class='const'>MySqlPlug</span><span class='period'>.</span><span class='id identifier rubyid_migrate'>migrate</span> <span class='int'>0</span>
228
+ <span class='comment'># =&gt; 0.0
229
+ </span></code></pre>
230
+
231
+ <p>This, will migrate everything down, reverting the changes as specified in each reverted migration <code>self.down</code> method.
232
+ <code>ruby
233
+ MySqlPlug.migrate 1.0
234
+ # =&gt; 1.0
235
+ </code>
236
+ And finally, this will migrate up until it hits 1.0.</p>
237
+
238
+ <h1>The Command Line Tool</h1>
239
+
240
+ <p>Active Record Binder ships with a neat little CLI : <code>arb</code></p>
241
+
242
+ <p>ARB is a small easily extandable Command Line Interface. And it&#39;s pretty. Beautiful colors everywhere. Awesome. Seriously.
243
+ To use it :
244
+ ```
245
+ $ arb version</p>
246
+
247
+ <h1>=&gt; Binder::AR::Version =&gt; 1.2.0</h1>
248
+
249
+ <pre class="code ruby"><code class="ruby">
250
+ You can display the help using `arb help` or `arb -h`
251
+
252
+ But, the most intersting part of this CLI is the migrate command. You can easily run your migrations for a specific plug :
253
+ </code></pre>
254
+
255
+ <p>$ arb migrate --version 1.1 --directory migrations/ --adapter MySqlitePlug
256
+ ``<code>
257
+ Will migrate to 1.1, using the migrations found in the</code>migrations/<code>directory and calling</code>MySqlitePlug.migrate`.</p>
258
+
259
+ <p>You can specify multiples options, and there is an alternative syntax :
260
+ ```</p>
261
+
262
+ <h1>=&gt; You can specify multiple directories through <code>--directory</code> or <code>--d</code></h1>
263
+
264
+ <p>$ arb migrate -v 0 -d migrations/foo/ migrations/bar -a MySqlitePlug</p>
265
+
266
+ <h1>=&gt; You can load directories recursively with <code>-r</code> or <code>--recursive</code></h1>
267
+
268
+ <p>$ arb migrate -v 0 --recursive migrations/ --plug MySqlitePlug</p>
269
+
270
+ <h1>=&gt; You can can also load files using <code>-f</code> or <code>--file</code></h1>
271
+
272
+ <p>$ arb migrate -v 1.0 -f migrations/foo/create_foo_table.rb --adapter MySqlitePlug
273
+ ```</p>
274
+
275
+ <p><img src="https://raw.github.com/gabriel-dehan/ActiveRecordBinder/master/extras/cli_help.png" alt="Command Line Interface screenshot"/></p>
276
+
277
+ <h1>Want to know more ?</h1>
278
+
279
+ <p><a href="http://rubydoc.info/gems/active-record-binder/1.0.1/frames">Checkout the documentation !</a>
280
+ Or dive in, the code is pretty straightforward and well documented. And there is a lot of tests.</p>
281
+
282
+ <h1>Want to contribute ?</h1>
283
+
284
+ <p>Please, do fork and pull request !</p>
285
+
286
+ <h2>Road map:</h2>
287
+
288
+ <ul>
289
+ <li>Maybe create other Binder, like MongoDB, Datamapper, like <code>Binder::Mongo</code>, <code>Binder::DataMapper</code>. But the gem&#39;s name would have to change.</li>
290
+ </ul>
291
+ </div></div>
292
+
293
+ <div id="footer">
294
+ Generated on Thu Feb 21 02:06:16 2013 by
295
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
296
+ 0.8.4.1 (ruby-1.9.3).
297
+ </div>
298
+
299
+ </body>
300
+ </html>
@@ -0,0 +1,55 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html>
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6
+
7
+ <link rel="stylesheet" href="css/full_list.css" type="text/css" media="screen" charset="utf-8" />
8
+
9
+ <link rel="stylesheet" href="css/common.css" type="text/css" media="screen" charset="utf-8" />
10
+
11
+
12
+
13
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
14
+
15
+ <script type="text/javascript" charset="utf-8" src="js/full_list.js"></script>
16
+
17
+
18
+ <base id="base_target" target="_parent" />
19
+ </head>
20
+ <body>
21
+ <script type="text/javascript" charset="utf-8">
22
+ if (window.top.frames.main) {
23
+ document.getElementById('base_target').target = 'main';
24
+ document.body.className = 'frames';
25
+ }
26
+ </script>
27
+ <div id="content">
28
+ <h1 id="full_list_header">File List</h1>
29
+ <div id="nav">
30
+
31
+ <span><a target="_self" href="class_list.html">
32
+ Classes
33
+ </a></span>
34
+
35
+ <span><a target="_self" href="method_list.html">
36
+ Methods
37
+ </a></span>
38
+
39
+ <span><a target="_self" href="file_list.html">
40
+ Files
41
+ </a></span>
42
+
43
+ </div>
44
+ <div id="search">Search: <input type="text" /></div>
45
+
46
+ <ul id="full_list" class="file">
47
+
48
+
49
+ <li class="r1"><a href="index.html" title="README">README</a></li>
50
+
51
+
52
+ </ul>
53
+ </div>
54
+ </body>
55
+ </html>
@@ -0,0 +1,28 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
3
+
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+ <head>
6
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
7
+ <title>Documentation by YARD 0.8.4.1</title>
8
+ </head>
9
+ <script type="text/javascript" charset="utf-8">
10
+ window.onload = function() {
11
+ var match = window.location.hash.match(/^#!(.+)/);
12
+ var name = 'index.html';
13
+ if (match) {
14
+ name = unescape(match[1]);
15
+ }
16
+ document.writeln('<frameset cols="20%,*">' +
17
+ '<frame name="list" src="class_list.html" />' +
18
+ '<frame name="main" src="' + name + '" />' +
19
+ '</frameset>');
20
+ }
21
+ </script>
22
+ <noscript>
23
+ <frameset cols="20%,*">
24
+ <frame name="list" src="class_list.html" />
25
+ <frame name="main" src="index.html" />
26
+ </frameset>
27
+ </noscript>
28
+ </html>
@@ -0,0 +1,300 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII" />
6
+ <title>
7
+ File: README
8
+
9
+ &mdash; Documentation by YARD 0.8.4.1
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="css/style.css" type="text/css" media="screen" charset="utf-8" />
14
+
15
+ <link rel="stylesheet" href="css/common.css" type="text/css" media="screen" charset="utf-8" />
16
+
17
+ <script type="text/javascript" charset="utf-8">
18
+ hasFrames = window.top.frames.main ? true : false;
19
+ relpath = '';
20
+ framesUrl = "frames.html#!" + escape(window.location.href);
21
+ </script>
22
+
23
+
24
+ <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
25
+
26
+ <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
27
+
28
+
29
+ </head>
30
+ <body>
31
+ <div id="header">
32
+ <div id="menu">
33
+
34
+ <a href="_index.html">Index</a> &raquo;
35
+ <span class="title">File: README</span>
36
+
37
+
38
+ <div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
39
+ </div>
40
+
41
+ <div id="search">
42
+
43
+ <a class="full_list_link" id="class_list_link"
44
+ href="class_list.html">
45
+ Class List
46
+ </a>
47
+
48
+ <a class="full_list_link" id="method_list_link"
49
+ href="method_list.html">
50
+ Method List
51
+ </a>
52
+
53
+ <a class="full_list_link" id="file_list_link"
54
+ href="file_list.html">
55
+ File List
56
+ </a>
57
+
58
+ </div>
59
+ <div class="clear"></div>
60
+ </div>
61
+
62
+ <iframe id="search_frame"></iframe>
63
+
64
+ <div id="content"><div id='filecontents'><h1><a href="https://rubygems.org/gems/active-record-binder">ActiveRecordBinder</a></h1>
65
+
66
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_arb'>arb</span> <span class='op'>-</span><span class='id identifier rubyid_v'>v</span>
67
+ <span class='comment'># =&gt; 1.2.0
68
+ </span>
69
+ <span class='id identifier rubyid_arb'>arb</span> <span class='op'>-</span><span class='op'>-</span><span class='id identifier rubyid_changelog'>changelog</span>
70
+ <span class='comment'># V 1.2.0 : Bug fixes, refactoring and introduction of the new command-line-tool : `arb`
71
+ </span><span class='comment'># V 1.1.0 : Introducing delegation for ActiveRecord::Base relation methods.
72
+ </span><span class='comment'># V 1.0.1 : Minor fixes and Documentation creation.
73
+ </span><span class='comment'># V 1.0.0 : Release
74
+ </span><span class='comment'>#
75
+ </span></code></pre>
76
+
77
+ <p>A Ruby library for an easier interfacing with ActiveRecord. And an easier way to create elegant migrations.</p>
78
+
79
+ <h1>Installation</h1>
80
+
81
+ <p><code>gem install active-record-binder</code></p>
82
+
83
+ <h1>Why Binder ? What the frak is this ?</h1>
84
+
85
+ <p>I needed a tool to ease the creation of little Plugs and Adapters for ActiveRecord.</p>
86
+
87
+ <p>The idea is that you Bind a class to ActiveRecord by subclassing it with Binder::AR.
88
+ You can specify your own methods and delegate to ActiveRecord whenever you need.</p>
89
+
90
+ <p>It&#39;s kind of a Proxy on steroids, that will do a lot for you.</p>
91
+
92
+ <h2>Show me !</h2>
93
+
94
+ <p>You want to create a Plug for your sqlite database :</p>
95
+
96
+ <pre class="code ruby"><code class="ruby"> <span class='kw'>class</span> <span class='const'>SqlitePlug</span> <span class='op'>&lt;</span> <span class='const'>Binder</span><span class='op'>::</span><span class='const'>AR</span>
97
+ <span class='kw'>end</span>
98
+ </code></pre>
99
+
100
+ <p>Those lines will create a new <code>MySqlPlug</code>, and it will connect to the database specified by your <code>ENV[&#39;APP_DB&#39;]</code>.
101
+ Also, the database adapter defaults to <code>:sqlite3</code>.</p>
102
+
103
+ <p>Now. All this is fine. But you want more :
104
+ * You want to select a precise database without using <code>ENV[&#39;APP_DB&#39;]</code>;
105
+ * Your application uses MySQL.</p>
106
+
107
+ <pre class="code ruby"><code class="ruby"> <span class='kw'>class</span> <span class='const'>MySqlPlug</span> <span class='op'>&lt;</span> <span class='const'>Binder</span><span class='op'>::</span><span class='const'>AR</span>
108
+ <span class='id identifier rubyid_database'>database</span> <span class='symbol'>:db</span>
109
+ <span class='id identifier rubyid_adapter'>adapter</span> <span class='symbol'>:mysql</span>
110
+ <span class='id identifier rubyid_connect_with'>connect_with</span> <span class='label'>user:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>Foo</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>password:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>Bar</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>host:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>localhost</span><span class='tstring_end'>'</span></span>
111
+ <span class='kw'>end</span>
112
+ </code></pre>
113
+
114
+ <p>As you can see : you can specify a database or an adapter by passing a <code>Symbol</code> or a <code>String</code> to both the
115
+ * <code>database()</code> and the
116
+ * <code>adapter()</code> methods.</p>
117
+
118
+ <p>The <code>connect_with()</code> method can be used to pass a <code>Hash</code> of options to the <code>ActiveRecord::Base.establish_connexion()</code> call.</p>
119
+
120
+ <p><em>Please notice that all your instances of MySqlPlug will use those values once defined this way.</em></p>
121
+
122
+ <h2>How do we use this ?</h2>
123
+
124
+ <pre class="code ruby"><code class="ruby"> <span class='kw'>class</span> <span class='const'>MySqlPlug</span> <span class='op'>&lt;</span> <span class='const'>Binder</span><span class='op'>::</span><span class='const'>AR</span>
125
+ <span class='id identifier rubyid_database'>database</span> <span class='symbol'>:db</span>
126
+ <span class='id identifier rubyid_adapter'>adapter</span> <span class='symbol'>:mysql</span>
127
+ <span class='id identifier rubyid_connect_with'>connect_with</span> <span class='label'>user:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>Foo</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>password:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>Bar</span><span class='tstring_end'>'</span></span><span class='comma'>,</span> <span class='label'>host:</span> <span class='tstring'><span class='tstring_beg'>'</span><span class='tstring_content'>localhost</span><span class='tstring_end'>'</span></span>
128
+
129
+ <span class='kw'>def</span> <span class='id identifier rubyid_find'>find</span> <span class='id identifier rubyid_args'>args</span>
130
+ <span class='comment'># But you could use a delegator
131
+ </span> <span class='id identifier rubyid_table'>table</span><span class='period'>.</span><span class='id identifier rubyid_find'>find</span> <span class='id identifier rubyid_args'>args</span>
132
+ <span class='kw'>end</span>
133
+ <span class='kw'>end</span>
134
+
135
+ <span class='comment'># A Model
136
+ </span> <span class='kw'>class</span> <span class='const'>Foo</span>
137
+ <span class='kw'>def</span> <span class='id identifier rubyid_initialize'>initialize</span>
138
+ <span class='comment'># Will bind this instance of the MySqlPlug to the `foos` table
139
+ </span> <span class='ivar'>@plug</span> <span class='op'>=</span> <span class='const'>MySqlPlug</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='symbol'>:foo</span>
140
+ <span class='kw'>end</span>
141
+
142
+ <span class='kw'>def</span> <span class='id identifier rubyid_find'>find</span>
143
+ <span class='comment'># But you could use a delegator
144
+ </span> <span class='ivar'>@plug</span><span class='period'>.</span><span class='id identifier rubyid_find'>find</span>
145
+ <span class='kw'>end</span>
146
+ <span class='kw'>end</span>
147
+ </code></pre>
148
+
149
+ <p><strong>Note :</strong> You can use the <code>table</code> method on any instance of your Plug to get the table class (An ActiveRecord Class Object).</p>
150
+
151
+ <pre class="code ruby"><code class="ruby"> <span class='ivar'>@plug</span> <span class='op'>=</span> <span class='const'>MySqlPlug</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='symbol'>:foo</span>
152
+ <span class='id identifier rubyid_table'>table</span> <span class='op'>=</span> <span class='ivar'>@plug</span><span class='period'>.</span><span class='id identifier rubyid_table'>table</span>
153
+ <span class='comment'># =&gt; MySqlPlug::Foo
154
+ </span> <span class='id identifier rubyid_table'>table</span><span class='period'>.</span><span class='id identifier rubyid_find'>find</span> <span class='comment'># ActiveRecord method call.
155
+ </span> <span class='comment'># =&gt; [&lt;FooObject#1&gt;, &lt;FooObject#2, ...]
156
+ </span></code></pre>
157
+
158
+ <p>Notice how neatly namespaced is the ActiveRecord table class. This way we won&#39;t step over our <code>Foo</code> model.</p>
159
+
160
+ <h1>Relations</h1>
161
+
162
+ <p>If it pleases you, you can create your relations directly in the Binder class. Those methods call are delegated to the underlying table model when initiated.</p>
163
+
164
+ <pre class="code ruby"><code class="ruby"> <span class='kw'>class</span> <span class='const'>FooBinder</span> <span class='op'>&lt;</span> <span class='const'>Binder</span><span class='op'>::</span><span class='const'>AR</span>
165
+ <span class='id identifier rubyid_has_one'>has_one</span> <span class='symbol'>:bar</span>
166
+ <span class='kw'>end</span>
167
+ <span class='kw'>class</span> <span class='const'>BarBinder</span> <span class='op'>&lt;</span> <span class='const'>Binder</span><span class='op'>::</span><span class='const'>AR</span>
168
+ <span class='id identifier rubyid_belongs_to'>belongs_to</span> <span class='symbol'>:foo</span>
169
+ <span class='kw'>end</span>
170
+
171
+ <span class='comment'># And (if the table are accordingly populated, see &quot;The Migration System&quot;, below) :
172
+ </span> <span class='id identifier rubyid_foo'>foo</span> <span class='op'>=</span> <span class='const'>FooBinder</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span><span class='lparen'>(</span><span class='symbol'>:foo</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_table'>table</span>
173
+ <span class='id identifier rubyid_foo'>foo</span><span class='period'>.</span><span class='id identifier rubyid_first'>first</span><span class='period'>.</span><span class='id identifier rubyid_bar'>bar</span> <span class='comment'># =&gt; &lt;BarObject&gt;
174
+ </span></code></pre>
175
+
176
+ <p>Delegated methods are the following : <code>has_many</code>, <code>has_one</code>, <code>has_and_belongs_to_many</code>, <code>belongs_to</code>.</p>
177
+
178
+ <h1>The Migration System</h1>
179
+
180
+ <p>I&#39;ve always found the ActiveRecord::Migration system a bit of a pain to use.</p>
181
+
182
+ <p>Therefore, I took the liberty of using pieces of <a href="https://github.com/camping/camping/"><code>_Why&#39;s Camping Web Framework&#39;s</code></a> migration system.
183
+ You can now create your migrations this way :</p>
184
+
185
+ <pre class="code ruby"><code class="ruby"> <span class='kw'>class</span> <span class='const'>CreateFooTable</span> <span class='op'>&lt;</span> <span class='const'>MySqlPlug</span><span class='op'>::</span><span class='const'>Version</span> <span class='float'>1.0</span>
186
+ <span class='kw'>def</span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_up'>up</span>
187
+ <span class='id identifier rubyid_create_table'>create_table</span> <span class='symbol'>:foos</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_t'>t</span><span class='op'>|</span>
188
+ <span class='id identifier rubyid_t'>t</span><span class='period'>.</span><span class='id identifier rubyid_string'>string</span> <span class='symbol'>:name</span>
189
+ <span class='id identifier rubyid_t'>t</span><span class='period'>.</span><span class='id identifier rubyid_timestamps'>timestamps</span>
190
+ <span class='kw'>end</span>
191
+ <span class='kw'>end</span>
192
+
193
+ <span class='kw'>def</span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_down'>down</span>
194
+ <span class='id identifier rubyid_drop_table'>drop_table</span> <span class='symbol'>:foos</span>
195
+ <span class='kw'>end</span>
196
+ <span class='kw'>end</span>
197
+
198
+ <span class='kw'>class</span> <span class='const'>CreateBarTable</span> <span class='op'>&lt;</span> <span class='const'>MySqlPlug</span><span class='op'>::</span><span class='const'>Version</span> <span class='float'>1.1</span>
199
+ <span class='kw'>def</span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_up'>up</span>
200
+ <span class='id identifier rubyid_create_table'>create_table</span> <span class='symbol'>:bars</span> <span class='kw'>do</span> <span class='op'>|</span><span class='id identifier rubyid_t'>t</span><span class='op'>|</span>
201
+ <span class='id identifier rubyid_t'>t</span><span class='period'>.</span><span class='id identifier rubyid_string'>string</span> <span class='symbol'>:title</span>
202
+ <span class='id identifier rubyid_t'>t</span><span class='period'>.</span><span class='id identifier rubyid_timestamps'>timestamps</span>
203
+ <span class='kw'>end</span>
204
+ <span class='kw'>end</span>
205
+
206
+ <span class='kw'>def</span> <span class='kw'>self</span><span class='period'>.</span><span class='id identifier rubyid_down'>down</span>
207
+ <span class='id identifier rubyid_drop_table'>drop_table</span> <span class='symbol'>:bars</span>
208
+ <span class='kw'>end</span>
209
+ <span class='kw'>end</span>
210
+
211
+ <span class='comment'># You can get the migration version for a pecular migration class.
212
+ </span> <span class='const'>CreateFooTable</span><span class='period'>.</span><span class='id identifier rubyid_version'>version</span> <span class='comment'># =&gt; 1.0
213
+ </span> <span class='const'>CreateBarTable</span><span class='period'>.</span><span class='id identifier rubyid_version'>version</span> <span class='comment'># =&gt; 1.1
214
+ </span></code></pre>
215
+
216
+ <p>Isn&#39;t it neat ?.</p>
217
+
218
+ <p>Now, boy : just use the <code>migrate</code> method to execute your migrations.</p>
219
+
220
+ <pre class="code ruby"><code class="ruby"> <span class='const'>MySqlPlug</span><span class='period'>.</span><span class='id identifier rubyid_migrate'>migrate</span>
221
+ <span class='comment'># =&gt; 1.1
222
+ </span></code></pre>
223
+
224
+ <p>This executes everything up to the latest migration.
225
+ But <code>migrate()</code> can also take a version number as an argument.</p>
226
+
227
+ <pre class="code ruby"><code class="ruby"> <span class='const'>MySqlPlug</span><span class='period'>.</span><span class='id identifier rubyid_migrate'>migrate</span> <span class='int'>0</span>
228
+ <span class='comment'># =&gt; 0.0
229
+ </span></code></pre>
230
+
231
+ <p>This, will migrate everything down, reverting the changes as specified in each reverted migration <code>self.down</code> method.
232
+ <code>ruby
233
+ MySqlPlug.migrate 1.0
234
+ # =&gt; 1.0
235
+ </code>
236
+ And finally, this will migrate up until it hits 1.0.</p>
237
+
238
+ <h1>The Command Line Tool</h1>
239
+
240
+ <p>Active Record Binder ships with a neat little CLI : <code>arb</code></p>
241
+
242
+ <p>ARB is a small easily extandable Command Line Interface. And it&#39;s pretty. Beautiful colors everywhere. Awesome. Seriously.
243
+ To use it :
244
+ ```
245
+ $ arb version</p>
246
+
247
+ <h1>=&gt; Binder::AR::Version =&gt; 1.2.0</h1>
248
+
249
+ <pre class="code ruby"><code class="ruby">
250
+ You can display the help using `arb help` or `arb -h`
251
+
252
+ But, the most intersting part of this CLI is the migrate command. You can easily run your migrations for a specific plug :
253
+ </code></pre>
254
+
255
+ <p>$ arb migrate --version 1.1 --directory migrations/ --adapter MySqlitePlug
256
+ ``<code>
257
+ Will migrate to 1.1, using the migrations found in the</code>migrations/<code>directory and calling</code>MySqlitePlug.migrate`.</p>
258
+
259
+ <p>You can specify multiples options, and there is an alternative syntax :
260
+ ```</p>
261
+
262
+ <h1>=&gt; You can specify multiple directories through <code>--directory</code> or <code>--d</code></h1>
263
+
264
+ <p>$ arb migrate -v 0 -d migrations/foo/ migrations/bar -a MySqlitePlug</p>
265
+
266
+ <h1>=&gt; You can load directories recursively with <code>-r</code> or <code>--recursive</code></h1>
267
+
268
+ <p>$ arb migrate -v 0 --recursive migrations/ --plug MySqlitePlug</p>
269
+
270
+ <h1>=&gt; You can can also load files using <code>-f</code> or <code>--file</code></h1>
271
+
272
+ <p>$ arb migrate -v 1.0 -f migrations/foo/create_foo_table.rb --adapter MySqlitePlug
273
+ ```</p>
274
+
275
+ <p><img src="https://raw.github.com/gabriel-dehan/ActiveRecordBinder/master/extras/cli_help.png" alt="Command Line Interface screenshot"/></p>
276
+
277
+ <h1>Want to know more ?</h1>
278
+
279
+ <p><a href="http://rubydoc.info/gems/active-record-binder/1.0.1/frames">Checkout the documentation !</a>
280
+ Or dive in, the code is pretty straightforward and well documented. And there is a lot of tests.</p>
281
+
282
+ <h1>Want to contribute ?</h1>
283
+
284
+ <p>Please, do fork and pull request !</p>
285
+
286
+ <h2>Road map:</h2>
287
+
288
+ <ul>
289
+ <li>Maybe create other Binder, like MongoDB, Datamapper, like <code>Binder::Mongo</code>, <code>Binder::DataMapper</code>. But the gem&#39;s name would have to change.</li>
290
+ </ul>
291
+ </div></div>
292
+
293
+ <div id="footer">
294
+ Generated on Thu Feb 21 02:06:16 2013 by
295
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
296
+ 0.8.4.1 (ruby-1.9.3).
297
+ </div>
298
+
299
+ </body>
300
+ </html>