Merged 14009:14059 from trunk.
[rails.git] / vendor / gems / composite_primary_keys-1.1.0 / website / index.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4 <head>
5   <link rel="stylesheet" href="stylesheets/screen.css" type="text/css" media="screen" />
6   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7   <title>
8       Composite Primary Keys
9   </title>
10   <script src="javascripts/rounded_corners_lite.inc.js" type="text/javascript"></script>
11 <style>
12
13 </style>
14   <script type="text/javascript">
15     window.onload = function() {
16       settings = {
17           tl: { radius: 10 },
18           tr: { radius: 10 },
19           bl: { radius: 10 },
20           br: { radius: 10 },
21           antiAlias: true,
22           autoPad: true,
23           validTags: ["div"]
24       }
25       var versionBox = new curvyCorners(settings, document.getElementById("version"));
26       versionBox.applyCornersToAll();
27     }
28   </script>
29 </head>
30 <body>
31 <div id="main">
32
33     <h1>Composite Primary Keys</h1>
34     <div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/compositekeys"; return false'>
35       Get Version
36       <a href="http://rubyforge.org/projects/compositekeys" class="numbers">1.1.0</a>
37     </div>
38     <h1>&amp;#x2192; Ruby on Rails</h1>
39 <h1>&amp;#x2192; ActiveRecords</h1>
40 <h2>What</h2>
41 <p>Ruby on Rails does not support composite primary keys. This free software is an extension <br />
42 to the database layer of Rails &#8211; <a href="http://wiki.rubyonrails.com/rails/pages/ActiveRecord">ActiveRecords</a> &#8211; to support composite primary keys as transparently as possible.</p>
43 <p>Any Ruby script using ActiveRecords can use Composite Primary Keys with this library.</p>
44 <h2>Installing</h2>
45 <p><pre class="syntax"><span class="ident">sudo</span> <span class="ident">gem</span> <span class="ident">install</span> <span class="ident">composite_primary_keys</span></pre></p>
46 <p>Rails: Add the following to the bottom of your <code>environment.rb</code> file</p>
47 <p><pre class="syntax"><span class="ident">require</span> <span class="punct">'</span><span class="string">composite_primary_keys</span><span class="punct">'</span></pre></p>
48 <p>Ruby scripts: Add the following to the top of your script</p>
49 <p><pre class="syntax"><span class="ident">require</span> <span class="punct">'</span><span class="string">rubygems</span><span class="punct">'</span>
50 <span class="ident">require</span> <span class="punct">'</span><span class="string">composite_primary_keys</span><span class="punct">'</span></pre></p>
51 <h2>The basics</h2>
52 <p>A model with composite primary keys would look like&#8230;</p>
53 <p><pre class="syntax"><span class="keyword">class </span><span class="class">Membership</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
54   <span class="comment"># set_primary_keys *keys - turns on composite key functionality</span>
55   <span class="ident">set_primary_keys</span> <span class="symbol">:user_id</span><span class="punct">,</span> <span class="symbol">:group_id</span>
56   <span class="ident">belongs_to</span> <span class="symbol">:user</span>
57   <span class="ident">belongs_to</span> <span class="symbol">:group</span>
58   <span class="ident">has_many</span> <span class="symbol">:statuses</span><span class="punct">,</span> <span class="symbol">:class_name</span> <span class="punct">=&gt;</span> <span class="punct">'</span><span class="string">MembershipStatus</span><span class="punct">',</span> <span class="symbol">:foreign_key</span> <span class="punct">=&gt;</span> <span class="punct">[</span><span class="symbol">:user_id</span><span class="punct">,</span> <span class="symbol">:group_id</span><span class="punct">]</span>
59 <span class="keyword">end</span></pre></p>
60 <p>A model associated with a composite key model would be defined like&#8230;</p>
61 <p><pre class="syntax"><span class="keyword">class </span><span class="class">MembershipStatus</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>
62   <span class="ident">belongs_to</span> <span class="symbol">:membership</span><span class="punct">,</span> <span class="symbol">:foreign_key</span> <span class="punct">=&gt;</span> <span class="punct">[</span><span class="symbol">:user_id</span><span class="punct">,</span> <span class="symbol">:group_id</span><span class="punct">]</span>
63 <span class="keyword">end</span></pre></p>
64 <p>That is, associations can include composite keys too. Nice.</p>
65 <h2>Demonstration of usage</h2>
66 <p>Once you&#8217;ve created your models to specify composite primary keys (such as the Membership class) and associations (such as MembershipStatus#membership), you can uses them like any normal model with associations.</p>
67 <p>But first, lets check out our primary keys.</p>
68 <p><pre class="syntax"><span class="constant">MembershipStatus</span><span class="punct">.</span><span class="ident">primary_key</span> <span class="comment"># =&gt; &quot;id&quot;    # normal single key</span>
69 <span class="constant">Membership</span><span class="punct">.</span><span class="ident">primary_key</span>  <span class="comment"># =&gt; [:user_id, :group_id] # composite keys</span>
70 <span class="constant">Membership</span><span class="punct">.</span><span class="ident">primary_key</span><span class="punct">.</span><span class="ident">to_s</span> <span class="comment"># =&gt; &quot;user_id,group_id&quot;</span></pre></p>
71 <p>Now we want to be able to find instances using the same syntax we always use for ActiveRecords&#8230;</p>
72 <p><pre class="syntax"><span class="constant">MembershipStatus</span><span class="punct">.</span><span class="ident">find</span><span class="punct">(</span><span class="number">1</span><span class="punct">)</span>    <span class="comment"># single id returns single instance</span>
73 <span class="punct">=&gt;</span> <span class="punct">&lt;</span><span class="constant">MembershipStatus</span><span class="punct">:</span><span class="number">0x392a8c8</span> <span class="attribute">@attributes</span><span class="punct">={&quot;</span><span class="string">id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">status</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">Active</span><span class="punct">&quot;}&gt;</span>
74 <span class="constant">Membership</span><span class="punct">.</span><span class="ident">find</span><span class="punct">(</span><span class="number">1</span><span class="punct">,</span><span class="number">1</span><span class="punct">)</span>  <span class="comment"># composite ids returns single instance</span>
75 <span class="punct">=&gt;</span> <span class="punct">&lt;</span><span class="constant">Membership</span><span class="punct">:</span><span class="number">0x39218b0</span> <span class="attribute">@attributes</span><span class="punct">={&quot;</span><span class="string">user_id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">group_id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;}&gt;</span></pre></p>
76 <p>Using <a href="http://www.rubyonrails.org">Ruby on Rails</a>? You&#8217;ll want to your url_for helpers<br />
77 to convert composite keys into strings and back again&#8230;</p>
78 <p><pre class="syntax"><span class="constant">Membership</span><span class="punct">.</span><span class="ident">find</span><span class="punct">(</span><span class="symbol">:first</span><span class="punct">).</span><span class="ident">to_param</span> <span class="comment"># =&gt; &quot;1,1&quot;</span></pre></p>
79 <p>And then use the string id within your controller to find the object again</p>
80 <p><pre class="syntax"><span class="ident">params</span><span class="punct">[</span><span class="symbol">:id</span><span class="punct">]</span> <span class="comment"># =&gt; '1,1'</span>
81 <span class="constant">Membership</span><span class="punct">.</span><span class="ident">find</span><span class="punct">(</span><span class="ident">params</span><span class="punct">[</span><span class="symbol">:id</span><span class="punct">])</span>
82 <span class="punct">=&gt;</span> <span class="punct">&lt;</span><span class="constant">Membership</span><span class="punct">:</span><span class="number">0x3904288</span> <span class="attribute">@attributes</span><span class="punct">={&quot;</span><span class="string">user_id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">group_id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;}&gt;</span></pre></p>
83 <p>That is, an ActiveRecord supporting composite keys behaves transparently<br />
84 throughout your application. Just like a normal ActiveRecord.</p>
85 <h2>Other tricks</h2>
86 <h3>Pass a list of composite ids to the <code>#find</code> method</h3>
87 <p><pre class="syntax"><span class="constant">Membership</span><span class="punct">.</span><span class="ident">find</span> <span class="punct">[</span><span class="number">1</span><span class="punct">,</span><span class="number">1</span><span class="punct">],</span> <span class="punct">[</span><span class="number">2</span><span class="punct">,</span><span class="number">1</span><span class="punct">]</span>
88 <span class="punct">=&gt;</span> <span class="punct">[</span>
89   <span class="punct">&lt;</span><span class="constant">Membership</span><span class="punct">:</span><span class="number">0x394ade8</span> <span class="attribute">@attributes</span><span class="punct">={&quot;</span><span class="string">user_id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">group_id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;}&gt;,</span> 
90   <span class="punct">&lt;</span><span class="constant">Membership</span><span class="punct">:</span><span class="number">0x394ada0</span> <span class="attribute">@attributes</span><span class="punct">={&quot;</span><span class="string">user_id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">2</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">group_id</span><span class="punct">&quot;=&gt;&quot;</span><span class="string">1</span><span class="punct">&quot;}&gt;</span>
91 <span class="punct">]</span></pre></p>
92 <p>Perform <code>#count</code> operations</p>
93 <p><pre class="syntax"><span class="constant">MembershipStatus</span><span class="punct">.</span><span class="ident">find</span><span class="punct">(</span><span class="symbol">:first</span><span class="punct">).</span><span class="ident">memberships</span><span class="punct">.</span><span class="ident">count</span> <span class="comment"># =&gt; 1</span></pre></p>
94 <h3>Routes with Rails</h3>
95 <p>From Pete Sumskas:</p>
96 <blockquote>
97 <p>I ran into one problem that I didn&#8217;t see mentioned on <a href="http://groups.google.com/group/compositekeys">this list</a> &#8211; <br />
98         and I   didn&#8217;t see any information about what I should do to address it in the<br />
99         documentation (might have missed it).</p>
100 <p>The problem was that the urls being generated for a &#8216;show&#8217; action (for<br />
101         example) had a syntax like:<br />
102         <br />
103         <pre>/controller/show/123000,Bu70</pre></p>
104 <p>for a two-field composite PK. The default routing would not match that,<br />
105         so after working out how to do the routing I added:<br />
106         <br />
107         <pre class="syntax"><span class="ident">map</span><span class="punct">.</span><span class="ident">connect</span> <span class="punct">'</span><span class="string">:controller/:action/:id</span><span class="punct">',</span> <span class="symbol">:id</span> <span class="punct">=&gt;</span> <span class="punct">/</span><span class="regex"><span class="escape">\w</span>+(,<span class="escape">\w</span>+)*</span><span class="punct">/</span></pre><br />
108         <br />
109         to my <code>route.rb</code> file.</p>
110 </blockquote>
111 <p><a name="dbs"></a></p>
112 <h2>Which databases?</h2>
113 <p>A suite of unit tests have been run on the following databases supported by ActiveRecord:</p>
114 <table>
115         <tr>
116                 <th>Database</th>
117                 <th>Test Success</th>
118                 <th>User feedback</th>
119         </tr>
120         <tr>
121                 <td>mysql     </td>
122                 <td><span class=success><span class="caps">YES</span></span></td>
123                 <td><span class=success><span class="caps">YES</span></span> (<a href="mailto:compositekeys@googlegroups.com?subject=Mysql+is+working">Yes!</a> or <a href="mailto:compositekeys@googlegroups.com?subject=Mysql+is+failing">No&#8230;</a>)</td>
124         </tr>
125         <tr>
126                 <td>sqlite3   </td>
127                 <td><span class=success><span class="caps">YES</span></span></td>
128                 <td><span class=success><span class="caps">YES</span></span> (<a href="mailto:compositekeys@googlegroups.com?subject=Sqlite3+is+working">Yes!</a> or <a href="mailto:compositekeys@googlegroups.com?subject=Sqlite3+is+failing">No&#8230;</a>)</td>
129         </tr>
130         <tr>
131                 <td>postgresql</td>
132                 <td><span class=success><span class="caps">YES</span></span></td>
133                 <td><span class=success><span class="caps">YES</span></span> (<a href="mailto:compositekeys@googlegroups.com?subject=Postgresql+is+working">Yes!</a> or <a href="mailto:compositekeys@googlegroups.com?subject=Postgresql+is+failing">No&#8230;</a>)</td>
134         </tr>
135         <tr>
136                 <td>oracle    </td>
137                 <td><span class=success><span class="caps">YES</span></span></td>
138                 <td><span class=success><span class="caps">YES</span></span> (<a href="mailto:compositekeys@googlegroups.com?subject=Oracle+is+working">Yes!</a> or <a href="mailto:compositekeys@googlegroups.com?subject=Oracle+is+failing">No&#8230;</a>)</td>
139         </tr>
140         <tr>
141                 <td>sqlserver </td>
142                 <td><span class=unknown>???</span> (<a href="mailto:compositekeys@googlegroups.com?subject=Help+with+SQLServer">I can help</a>)</td>
143                 <td><span class=unknown>???</span> (<a href="mailto:compositekeys@googlegroups.com?subject=SQLServer+is+working">Yes!</a> or <a href="mailto:compositekeys@googlegroups.com?subject=SQLServer+is+failing">No&#8230;</a>)</td>
144         </tr>
145         <tr>
146                 <td>db2       </td>
147                 <td><span class=unknown>???</span> (<a href="mailto:compositekeys@googlegroups.com?subject=Help+with+DB2">I can help</a>)</td>
148                 <td><span class=unknown>???</span> (<a href="mailto:compositekeys@googlegroups.com?subject=DB2+is+working">Yes!</a> or <a href="mailto:compositekeys@googlegroups.com?subject=DB2+is+failing">No&#8230;</a>)</td>
149         </tr>
150         <tr>
151                 <td>firebird  </td>
152                 <td><span class=unknown>???</span> (<a href="mailto:compositekeys@googlegroups.com?subject=Help+with+Firebird">I can help</a>)</td>
153                 <td><span class=unknown>???</span> (<a href="mailto:compositekeys@googlegroups.com?subject=Firebird+is+working">Yes!</a> or <a href="mailto:compositekeys@googlegroups.com?subject=Firebird+is+failing">No&#8230;</a>)</td>
154         </tr>
155         <tr>
156                 <td>sybase    </td>
157                 <td><span class=unknown>???</span> (<a href="mailto:compositekeys@googlegroups.com?subject=Help+with+Sybase">I can help</a>)</td>
158                 <td><span class=unknown>???</span> (<a href="mailto:compositekeys@googlegroups.com?subject=Sybase+is+working">Yes!</a> or <a href="mailto:compositekeys@googlegroups.com?subject=Sybase+is+failing">No&#8230;</a>)</td>
159         </tr>
160         <tr>
161                 <td>openbase  </td>
162                 <td><span class=unknown>???</span> (<a href="mailto:compositekeys@googlegroups.com?subject=Help+with+Openbase">I can help</a>)</td>
163                 <td><span class=unknown>???</span> (<a href="mailto:compositekeys@googlegroups.com?subject=Openbase+is+working">Yes!</a> or <a href="mailto:compositekeys@googlegroups.com?subject=Openbase+is+failing">No&#8230;</a>)</td>
164         </tr>
165         <tr>
166                 <td>frontbase </td>
167                 <td><span class=unknown>???</span> (<a href="mailto:compositekeys@googlegroups.com?subject=Help+with+Frontbase">I can help</a>)</td>
168                 <td><span class=unknown>???</span> (<a href="mailto:compositekeys@googlegroups.com?subject=Frontbase+is+working">Yes!</a> or <a href="mailto:compositekeys@googlegroups.com?subject=Frontbase+is+failing">No&#8230;</a>)</td>
169         </tr>
170 </table>
171 <h2>Dr Nic&#8217;s Blog</h2>
172 <p><a href="http://www.drnicwilliams.com">http://www.drnicwilliams.com</a> &#8211; for future announcements and<br />
173 other stories and things.</p>
174 <h2>Forum</h2>
175 <p><a href="http://groups.google.com/group/compositekeys">http://groups.google.com/group/compositekeys</a></p>
176 <h2>How to submit patches</h2>
177 <p>Read the <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/">8 steps for fixing other people&#8217;s code</a> and for section <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/#8b-google-groups">8b: Submit patch to Google Groups</a>, use the Google Group above.</p>
178 <p>The source for this project is available via git. You can <a href="http://github.com/drnic/composite_primary_keys/tree/master">browse and/or fork the source</a>, or to clone the project locally:<br />
179   <br />
180 <pre>git clone git://github.com/drnic/composite_primary_keys.git</pre></p>
181 <h2>Licence</h2>
182 <p>This code is free to use under the terms of the <span class="caps">MIT</span> licence.</p>
183 <h2>Contact</h2>
184 <p>Comments are welcome. Send an email to <a href="mailto:drnicwilliams@gmail.com">Dr Nic Williams</a>.</p>
185     <p class="coda">
186       <a href="mailto:drnicwilliams@gmail.com">Dr Nic</a>, 25th October 2008<br>
187       Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
188     </p>
189 </div>
190
191 <script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
192 </script>
193 <script type="text/javascript">
194 _uacct = "UA-567811-2";
195 urchinTracker();
196 </script>
197
198 </body>
199 </html>