active-record-binder 1.1.0 → 1.2.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 (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>