<?xml version="1.0"?>
<rss version="2.0">
  <channel><title>ModelDemo</title><link>http://bill.welliver.org//space/pike/Fins/Developer/ModelDemo</link><description>Below is a simple example of the steps for setting up a simple database driven application using Fins. Commands that should be typed are listed in bold.&lt;p class="paragraph"/&gt;
&amp;#49;. Download Fins, unpack and change into the Fins directory.&#xD;
&lt;div class="code"&gt;&lt;pre&gt;&lt;pre&gt;&#xD;
hera:/tmp hww3$ &lt;b class="bold"&gt;curl -o Fins.zip http:&lt;font color=red&gt;//hww3.riverweb.com/dist/Fins/Fins-0.2.zip&lt;/b&gt;&#xD;
&lt;/font&gt;% Total % Received % Xferd Average Speed Time Time Time Current&#xD;
Dload Upload Total Spent Left Speed&#xD;
100 760k 100 760k 0 0 83665 0 0:00:09 0:00:09 &lt;strike class="strike"&gt;:&lt;/strike&gt;:-- 98487&#xD;
hera:/tmp hww3$ &lt;b class="bold"&gt;unzip Fins.zip&lt;/b&gt;&#xD;
Archive: Fins.zip&#xD;
hera:/tmp hww3$ &lt;b class="bold"&gt;cd Fins-0.2/&lt;/b&gt;&#xD;
&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="paragraph"/&gt;
&#xD;
2. Create a new Fins application, called "&lt;i class="ital"&gt;widgetco&lt;/i&gt;".&lt;p class="paragraph"/&gt;
&lt;div class="code"&gt;&lt;pre&gt;&lt;pre&gt;&#xD;
hera:/tmp/Fins-0.2 hww3$ &lt;b class="bold"&gt;pike -Mlib -x fins create widgetco&lt;/b&gt;&#xD;
/18:35:17 INFO - CreateApplication module loading&#xD;
18:35:17 INFO - CreateApplication module running.&#xD;
18:35:17 INFO - Creating application widgetco in /private/tmp/Fins-0.2.&#xD;
18:35:17 INFO - Be sure to edit config/*.cfg to specify the application's datasource&#xD;
&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="paragraph"/&gt;
&#xD;
3. Create a new database and grant a user permission to that new database.&lt;p class="paragraph"/&gt;
&lt;div class="code"&gt;&lt;pre&gt;&lt;pre&gt;&#xD;
hera:/tmp/Fins-0.2 hww3$ &lt;b class="bold"&gt;mysqladmin -p create -uroot foo&lt;/b&gt;&#xD;
Enter password:&#xD;
hera:/tmp/Fins-0.2 hww3$ &lt;b class="bold"&gt;mysql -uroot foo -p&lt;/b&gt;&#xD;
Enter password:&#xD;
Welcome to the MySQL monitor. Commands end with ; or &amp;amp;&lt;font color=brown&gt;#103;.&#xD;
&lt;/font&gt;Your MySQL connection id is 18 to server version: 5.0.27-standard&lt;p class="paragraph"/&gt;
Type 'help;' or '&amp;amp;&lt;font color=brown&gt;#104;' for help. Type '&amp;amp;#99;' to clear the buffer.&#xD;
&lt;/font&gt;&#xD;
mysql&amp;gt; &lt;b class="bold"&gt;grant all on foo.* to foo identified by 'foo4u';&lt;/b&gt;&#xD;
Query OK, 0 rows affected (0.01 sec)&#xD;
&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="paragraph"/&gt;
&#xD;
4. We want to store records about Manufacturers and Widgets in our database, so let's create those tables in our new database.&lt;p class="paragraph"/&gt;
&lt;div class="code"&gt;&lt;pre&gt;&lt;pre&gt;&#xD;
mysql&amp;gt; &lt;b class="bold"&gt;create table widgets(&#xD;
id &lt;b&gt;&lt;font color=darkgreen&gt;int(11)&lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt; not&lt;/font&gt;&lt;/b&gt; null auto_increment primary key,&#xD;
name char(32),&#xD;
on_hand &lt;b&gt;&lt;font color=darkgreen&gt;int(11)&lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt; &lt;/font&gt;&lt;/b&gt;,&#xD;
manufacturer_id &lt;b&gt;&lt;font color=darkgreen&gt;int(11)&lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;&lt;/font&gt;&lt;/b&gt;);&lt;/b&gt;&#xD;
Query OK, 0 rows affected (0.00 sec)&lt;p class="paragraph"/&gt;
mysql&amp;gt; &lt;b class="bold"&gt;create table manufacturers(&#xD;
id &lt;b&gt;&lt;font color=darkgreen&gt;int(11)&lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt; not&lt;/font&gt;&lt;/b&gt; null auto_increment primary key,&#xD;
name char(32),&#xD;
phone_number char(16)&#xD;
);&lt;/b&gt;&#xD;
Query OK, 0 rows affected (0.00 sec)&lt;p class="paragraph"/&gt;
mysql&amp;gt; &lt;b class="bold"&gt;quit&lt;/b&gt;&#xD;
Bye&#xD;
&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="paragraph"/&gt;
&#xD;
5. Edit the configuration file so that the model knows what database to connect to. Set the sqlurl of the database you just created in the "&lt;i class="ital"&gt;datasource&lt;/i&gt;" configuration value of the "&lt;i class="ital"&gt;model&lt;/i&gt;" section so that fins can connect to your new database.&lt;p class="paragraph"/&gt;
&lt;div class="code"&gt;&lt;pre&gt;&lt;pre&gt;&#xD;
hera:/tmp/Fins-0.2 hww3$ &lt;b class="bold"&gt;vi widgetco/config/dev.cfg&lt;/b&gt;&#xD;
&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="paragraph"/&gt;
&#xD;
6. Now, let's set up the FINS_HOME environment variable so that we can use the scripts in the application directory. You could type the full commands out, but using the scripts will save typing.&lt;p class="paragraph"/&gt;
&lt;div class="code"&gt;&lt;pre&gt;&lt;pre&gt;&#xD;
hera:/tmp/Fins-0.2 hww3$ &lt;b class="bold"&gt;cd widgetco&lt;/b&gt;&#xD;
hera:/tmp/Fins-0.2/widgetco hww3$ &lt;b class="bold"&gt;export FINS_HOME=/tmp/Fins-0.2&lt;/b&gt;&#xD;
&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="paragraph"/&gt;
&#xD;
7. Let's start the app up, just to see what happens. You should get a message indicating the application is ready for business. If you don't or you get an error, double check your typing on the previous steps. You can stop the application by typing control-c.&lt;p class="paragraph"/&gt;
&lt;div class="code"&gt;&lt;pre&gt;&lt;pre&gt;&#xD;
hera:/tmp/Fins-0.2/widgetco hww3$ &lt;b class="bold"&gt;bin/start.sh&lt;/b&gt;&#xD;
18:43:08 INFO - FinServe starting on port 8080&#xD;
18:43:08 INFO - Starting Session Manager.&#xD;
18:43:08 INFO - FinServe loading application widgetco using configuration dev&#xD;
18:43:08 INFO - Starting Cache.&#xD;
18:43:08 INFO - loading model from model&#xD;
18:43:08 INFO - Application widgetco loaded.&#xD;
18:43:08 INFO - Application ready &lt;b&gt;&lt;font color=darkblue&gt;for&lt;/font&gt;&lt;/b&gt; business.&#xD;
&lt;b class="bold"&gt;&amp;lt;CTRL-C&amp;gt;&lt;/b&gt;&#xD;
hera:/tmp/Fins-0.2/widgetco hww3$&#xD;
&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="paragraph"/&gt;
&#xD;
8. Let's tell fins about the new manufacturer and widget tables we've created in the database.&lt;p class="paragraph"/&gt;
&lt;div class="code"&gt;&lt;pre&gt;&lt;pre&gt;&#xD;
hera:/tmp/Fins-0.2/widgetco hww3$ &lt;b class="bold"&gt;bin/fins.sh model add manufacturers widgets&lt;/b&gt;&#xD;
&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="paragraph"/&gt;
&#xD;
9. Now that our model is connected to the database and we've created some basic data model mapping definitions, let's add some new records, using these newly created mapping definitions:&lt;p class="paragraph"/&gt;
&lt;div class="code"&gt;&lt;pre&gt;&lt;pre&gt;&#xD;
hera:/tmp/Fins-0.2/widgetco hww3$ &lt;b class="bold"&gt;bin/start.sh --hilfe&lt;/b&gt;&#xD;
18:52:33 INFO - Application widgetco loaded.&#xD;
Starting &lt;b&gt;&lt;font color=darkgreen&gt;int&lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;eractive&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color=darkgreen&gt;int&lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;erpreter...&lt;/font&gt;&lt;/b&gt;&#xD;
Fins 0.4 running Pike v7.8 release 352 / Hilfe v3.5 (Incremental Pike Frontend)&#xD;
&amp;gt; &lt;b class="bold"&gt;object m = widgetco.Objects.Manufacturer();&lt;/b&gt;&#xD;
&amp;gt; &lt;b class="bold"&gt;m&amp;#91;&lt;i&gt;&lt;font color=darkred&gt;"name"&lt;/font&gt;&lt;/i&gt;] = &lt;i&gt;&lt;font color=darkred&gt;"Spacely Sprockets"&lt;/font&gt;&lt;/i&gt;;&lt;/b&gt;&#xD;
(2) Result: &lt;i&gt;&lt;font color=darkred&gt;"Spacely Sprockets"&lt;/font&gt;&lt;/i&gt;&#xD;
&amp;gt; &lt;b class="bold"&gt;m-&amp;gt;save();&lt;/b&gt;&#xD;
(3) Result: 0&#xD;
&amp;gt; &lt;b class="bold"&gt;object m = widgetco.Objects.Manufacturer();&lt;/b&gt;&#xD;
&amp;gt; &lt;b class="bold"&gt;m&amp;#91;&lt;i&gt;&lt;font color=darkred&gt;"name"&lt;/font&gt;&lt;/i&gt;] = &lt;i&gt;&lt;font color=darkred&gt;"Cogswell Cogs"&lt;/font&gt;&lt;/i&gt;;&lt;/b&gt;&#xD;
(4) Result: &lt;i&gt;&lt;font color=darkred&gt;"Cogswell Cogs"&lt;/font&gt;&lt;/i&gt;&lt;b class="bold"&gt;&#xD;
&amp;gt; __m-&amp;gt;save();&lt;/b&gt;&#xD;
(5) Result: 0&#xD;
&amp;gt; &lt;b class="bold"&gt;object w = widgetco.Objects.Widget();&lt;/b&gt;&#xD;
&amp;gt; &lt;b class="bold"&gt;w&amp;#91;&lt;i&gt;&lt;font color=darkred&gt;"name"&lt;/font&gt;&lt;/i&gt;] = &lt;i&gt;&lt;font color=darkred&gt;"SuperCog 2000"&lt;/font&gt;&lt;/i&gt;;&lt;/b&gt;&#xD;
(6) Result: &lt;i&gt;&lt;font color=darkred&gt;"SuperCog 2000"&lt;/font&gt;&lt;/i&gt;&#xD;
&amp;gt; &lt;b class="bold"&gt;w&amp;#91;&lt;i&gt;&lt;font color=darkred&gt;"Manufacturer"&lt;/font&gt;&lt;/i&gt;] = m;&lt;/b&gt;&#xD;
(7) Result: Manufacturer(id=2)&#xD;
&amp;gt; &lt;b class="bold"&gt;w&amp;#91;&lt;i&gt;&lt;font color=darkred&gt;"on_hand"&lt;/font&gt;&lt;/i&gt;] = 12;&lt;/b&gt;&#xD;
(8) Result: 12&#xD;
&amp;gt; &lt;b class="bold"&gt;w-&amp;gt;save();&lt;/b&gt;&#xD;
(9) Result: 0&#xD;
&amp;gt; &lt;b class="bold"&gt;indices(w);&lt;/b&gt;&#xD;
(10) Result: ({ &lt;font color=red&gt;/* 4 elements */&lt;/font&gt;&#xD;
&lt;i&gt;&lt;font color=darkred&gt;"on_hand"&lt;/font&gt;&lt;/i&gt;,&#xD;
&lt;i&gt;&lt;font color=darkred&gt;"Manufacturer"&lt;/font&gt;&lt;/i&gt;,&#xD;
&lt;i&gt;&lt;font color=darkred&gt;"name"&lt;/font&gt;&lt;/i&gt;,&#xD;
&lt;i&gt;&lt;font color=darkred&gt;"id"&lt;/font&gt;&lt;/i&gt;&#xD;
})&#xD;
&amp;gt; w&amp;#91;&lt;i&gt;&lt;font color=darkred&gt;"Manufacturer"&lt;/font&gt;&lt;/i&gt;];&#xD;
(1) Result: Manufacturer(id=2/2)&#xD;
&amp;gt; &lt;b class="bold"&gt;w&amp;#91;&lt;i&gt;&lt;font color=darkred&gt;"Manufactuer"&lt;/font&gt;&lt;/i&gt;]&amp;#91;&lt;i&gt;&lt;font color=darkred&gt;"name"&lt;/font&gt;&lt;/i&gt;];&lt;/b&gt;&#xD;
(11) Result: &lt;i&gt;&lt;font color=darkred&gt;"Cogswell Cogs"&lt;/font&gt;&lt;/i&gt;&#xD;
&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="paragraph"/&gt;
&#xD;
10. That's all very nice, but the description of the object is a little unfriendly. let's fix that by setting an "alternate key" field. setting an alternate key field allows us to query by that field easily, and the value of the alternate key is used in debug displays. Note that Fins doesn't enforce uniqueness of the alternate key; you should use database level techniques to do this (for example, using the UNIQUE key type).&lt;p class="paragraph"/&gt;
To set an alternate key field, select the field you'd like to use, and edit that object type's model definition (in this example, modules/widgetco.pmod/Model.pmod/Manufacturer.pike:&lt;p class="paragraph"/&gt;
&lt;div class="code"&gt;&lt;pre&gt;&lt;pre&gt;&#xD;
hera:/tmp/Fins-0.2/widgetco hww3$ &lt;b class="bold"&gt;vi modules/widgetco.pmod/DataMappings.pmod/Manufacturer.pike&lt;/b&gt;&#xD;
&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="paragraph"/&gt;
&#xD;
&amp;#49;1. To the Manufacturer.pike class, we want to add a post_define() method, and set the alternate key field.&lt;p class="paragraph"/&gt;
&lt;div class="code"&gt;&lt;pre&gt;&lt;pre&gt;&#xD;
&lt;b&gt;&lt;font color=darkgreen&gt;void &lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;post_define&lt;/font&gt;&lt;/b&gt;() { set_alternate_key(&lt;i&gt;&lt;font color=darkred&gt;"name"&lt;/font&gt;&lt;/i&gt;); }&#xD;
&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="paragraph"/&gt;
&#xD;
12. Now, let's try a little of that again:&lt;p class="paragraph"/&gt;
&lt;div class="code"&gt;&lt;pre&gt;&lt;pre&gt;&#xD;
hera:/tmp/Fins-0.2/widgetco hww3$ &lt;b class="bold"&gt;bin/start.sh --hilfe&lt;/b&gt;&#xD;
20:24:22 INFO - FinServe starting on port 8080&#xD;
...&#xD;
Starting &lt;b&gt;&lt;font color=darkgreen&gt;int&lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;eractive&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color=darkgreen&gt;int&lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;erpreter...&lt;/font&gt;&lt;/b&gt;&#xD;
Fins 0.4 running Pike v7.8 release 352/ Hilfe v3.5 (Incremental Pike Frontend)&#xD;
&amp;gt; &lt;b class="bold"&gt;Fins.Model.find.manufacturers_by_id(1);&lt;/b&gt;&#xD;
(1) Result: Manufacturer(name=Spacely Sprockets)&#xD;
&amp;gt; &lt;b class="bold"&gt;Fins.Model.find.manufacturers_by_alternate(&lt;i&gt;&lt;font color=darkred&gt;"Cogswell Cogs"&lt;/font&gt;&lt;/i&gt;);&lt;/b&gt;&#xD;
(4) Result: Manufacturer(name=Cogswell Cogs)&#xD;
&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="paragraph"/&gt;
&#xD;
13. Next, let's add some validation to our model. Perhaps we should make sure that phone numbers are provided in a particular format. We can use validation to perform this task. Add the validation by editing &lt;i class="ital"&gt;modules/widgetco.pmod/DataMappings.pmod/Manufacturer.pike&lt;/i&gt;. Add the following lines of code and save the file:&lt;p class="paragraph"/&gt;
&lt;div class="code"&gt;&lt;pre&gt;&lt;pre&gt;&#xD;
&lt;font color=red&gt;// our simple phone number regexp. &#xD;
&lt;/font&gt;&lt;b&gt;&lt;font color=darkblue&gt;constant&lt;/font&gt;&lt;/b&gt; pnf = &lt;i&gt;&lt;font color=darkred&gt;"&amp;#91;0-9]&amp;#91;0-9]&amp;#91;0-9]-&amp;#91;0-9]&amp;#91;0-9]&amp;#91;0-9]-&amp;#91;0-9]&amp;#91;0-9]&amp;#91;0-9]&amp;#91;0-9]"&lt;/font&gt;&lt;/i&gt;; &#xD;
&lt;b&gt;&lt;font color=darkgreen&gt;void &lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;validate&lt;/font&gt;&lt;/b&gt;(&lt;b&gt;&lt;font color=darkgreen&gt;mapping &lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;changes&lt;/font&gt;&lt;/b&gt;, &lt;b&gt;&lt;font color=darkgreen&gt;object &lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;errors&lt;/font&gt;&lt;/b&gt;, &lt;b&gt;&lt;font color=darkgreen&gt;object &lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;i&lt;/font&gt;&lt;/b&gt;) &#xD;
{ &#xD;
  &lt;b&gt;&lt;font color=darkblue&gt;if&lt;/font&gt;&lt;/b&gt;(changes-&amp;gt;phone_number) &#xD;
  { &#xD;
    &lt;b&gt;&lt;font color=darkgreen&gt;object &lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;r&lt;/font&gt;&lt;/b&gt; = Regexp.SimpleRegexp(pnf); &#xD;
    &lt;b&gt;&lt;font color=darkblue&gt;if&lt;/font&gt;&lt;/b&gt;(!r-&amp;gt;match(changes-&amp;gt;phone_number))  &lt;font color=red&gt;// if we're not a valid phone number, complain.&#xD;
&lt;/font&gt;      errors-&amp;gt;add(&lt;i&gt;&lt;font color=darkred&gt;"phone_number"&lt;/font&gt;&lt;/i&gt;, &lt;i&gt;&lt;font color=darkred&gt;"must be in the format nnn-nnn-nnnn."&lt;/font&gt;&lt;/i&gt;); &#xD;
  } &#xD;
}&#xD;
&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="paragraph"/&gt;
&#xD;
14. Now, let's test the validation:&lt;p class="paragraph"/&gt;
&lt;div class="code"&gt;&lt;pre&gt;&lt;pre&gt;&#xD;
hera:/tmp/Fins-0.2/widgetco hww3$ &lt;b class="bold"&gt;bin/start.sh --hilfe&lt;/b&gt;&#xD;
20:24:22 INFO - FinServe starting on port 8080&#xD;
...&#xD;
Starting &lt;b&gt;&lt;font color=darkgreen&gt;int&lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;eractive&lt;/font&gt;&lt;/b&gt; &lt;b&gt;&lt;font color=darkgreen&gt;int&lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;erpreter...&lt;/font&gt;&lt;/b&gt;&#xD;
Fins 0.4 running Pike v7.8 release 352 / Hilfe v3.5 (Incremental Pike Frontend)&#xD;
&amp;gt; &lt;b class="bold"&gt;object m = Fins.Model.find.manufacturers_by_id(1);&lt;/b&gt;&#xD;
(1) Result: Manufacturer(name=Spacely Sprockets)&#xD;
&amp;gt; &lt;b class="bold"&gt;m&amp;#91;&lt;i&gt;&lt;font color=darkred&gt;"phone_number"&lt;/font&gt;&lt;/i&gt;] = &lt;i&gt;&lt;font color=darkred&gt;"8885551212"&lt;/font&gt;&lt;/i&gt;;&lt;/b&gt;&#xD;
Data Validation Error&#xD;
Phone number must be in the format nnn-nnn-nnnn.&#xD;
lib/Fins.pmod/Model.pmod/DataObject.pike:664:&#xD;
wooga.Model.Manufacturer()-&amp;gt;set(&lt;i&gt;&lt;font color=darkred&gt;"phone_number"&lt;/font&gt;&lt;/i&gt;,&lt;i&gt;&lt;font color=darkred&gt;"1234567890"&lt;/font&gt;&lt;/i&gt;,UNDEFINED,Manufac&#xD;
turer(name=Spacely Sprockets))&#xD;
lib/Fins.pmod/Model.pmod/DataObjectInstance.pike:223:&#xD;
Manufacturer(name=Spacely Sprockets)-&amp;gt;`&amp;#91;]=(&lt;i&gt;&lt;font color=darkred&gt;"phone_number"&lt;/font&gt;&lt;/i&gt;,&lt;i&gt;&lt;font color=darkred&gt;"1234567890"&lt;/font&gt;&lt;/i&gt;)&#xD;
&amp;gt;&#xD;
&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="paragraph"/&gt;
&#xD;
15. Finally, a web interface for adding and editing objects would be nice to have. We can use the &lt;i class="ital"&gt;ScaffoldController&lt;/i&gt; to do some of the setup work for us.&lt;p class="paragraph"/&gt;
Start by editing the master controller, &lt;i class="ital"&gt;classes/controller.pike&lt;/i&gt;, and add the following code, in order to make our widget and manufacturer controllers available off the root of the application:&lt;p class="paragraph"/&gt;
&lt;div class="code"&gt;&lt;pre&gt;&lt;pre&gt;&#xD;
&lt;b&gt;&lt;font color=darkgreen&gt;object &lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;manufacturers&lt;/font&gt;&lt;/b&gt;; &#xD;
&lt;b&gt;&lt;font color=darkgreen&gt;object &lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;widgets&lt;/font&gt;&lt;/b&gt;; &#xD;
&lt;b&gt;&lt;font color=darkgreen&gt;void &lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;start&lt;/font&gt;&lt;/b&gt;() &#xD;
{ &#xD;
  manufacturers = load_controller(&lt;i&gt;&lt;font color=darkred&gt;"mfg_controller"&lt;/font&gt;&lt;/i&gt;); &#xD;
  widgets = load_controller(&lt;i&gt;&lt;font color=darkred&gt;"widget_controller"&lt;/font&gt;&lt;/i&gt;); &#xD;
}&#xD;
&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="paragraph"/&gt;
&#xD;
16. Then, add the files &lt;i class="ital"&gt;classes/mfg_controller.pike&lt;/i&gt; and &lt;i class="ital"&gt;classes/widget_controller.pike&lt;/i&gt; that will provide our data editors. In the first file, &lt;i class="ital"&gt;classes/mfg_controller.pike&lt;/i&gt;, add the following lines:&lt;p class="paragraph"/&gt;
&lt;div class="code"&gt;&lt;pre&gt;&lt;pre&gt;&#xD;
&lt;b&gt;&lt;font color=darkblue&gt;inherit&lt;/font&gt;&lt;/b&gt; Fins.ScaffoldController;&lt;p class="paragraph"/&gt;
&lt;font color=red&gt;// What data type shall we build an editor scaffolding for?&#xD;
&lt;/font&gt;&lt;b&gt;&lt;font color=darkgreen&gt;string &lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;model_component&lt;/font&gt;&lt;/b&gt; = &lt;i&gt;&lt;font color=darkred&gt;"Manufacturer"&lt;/font&gt;&lt;/i&gt;;&#xD;
&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="paragraph"/&gt;
&#xD;
In the second file, &lt;i class="ital"&gt;classes/widget_controller.pike&lt;/i&gt;, add the following lines:&lt;p class="paragraph"/&gt;
&lt;div class="code"&gt;&lt;pre&gt;&lt;pre&gt;&#xD;
&lt;b&gt;&lt;font color=darkblue&gt;inherit&lt;/font&gt;&lt;/b&gt; Fins.ScaffoldController;&lt;p class="paragraph"/&gt;
&lt;font color=red&gt;// What data type shall we build an editor scaffolding for?&#xD;
&lt;/font&gt;&lt;b&gt;&lt;font color=darkgreen&gt;string &lt;/font&gt;&lt;/b&gt;&lt;b&gt;&lt;font color=darkbrown&gt;model_component&lt;/font&gt;&lt;/b&gt; = &lt;i&gt;&lt;font color=darkred&gt;"Widget"&lt;/font&gt;&lt;/i&gt;;&#xD;
&lt;/pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="paragraph"/&gt;
&#xD;
17. Then, simply restart and point your web browser to /manufacturers or /widgets to edit data in your model. You'll notice that validation code will be run and any errors will be passed up to the client in a friendly way. </description><generator>Fins 0.9.7</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs></channel>
</rss>
