<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jeff Douglas - Technology, Coding and Bears... OH MY! &#187; Code Sample</title>
	<atom:link href="http://blog.jeffdouglas.com/category/code-sample/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.jeffdouglas.com</link>
	<description>Get your head out of your #@! and into the clouds!</description>
	<lastBuildDate>Thu, 02 Feb 2012 11:57:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>&#8220;Chow Finder&#8221; &#8211; My Veterans Hackday 2011 App</title>
		<link>http://blog.jeffdouglas.com/2011/11/15/chow-finder/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=chow-finder</link>
		<comments>http://blog.jeffdouglas.com/2011/11/15/chow-finder/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 11:53:16 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[CloudSpokes]]></category>
		<category><![CDATA[Code Sample]]></category>
		<category><![CDATA[Heroku]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=4264</guid>
		<description><![CDATA[This is my submission for the LinkedIn Veterans Hackday 2011. CloudSpokes threw in an extra $100 for any member that submitted as an extra incentive. Our members created some pretty cool apps and I&#8217;ll be highlighting them shortly. Chow Finder is a mobile application for services members to easily locate dining facilities, aka &#8220;chow halls&#8221;, [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F11%2F15%2Fchow-finder%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F11%2F15%2Fchow-finder%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://blog.jeffdouglas.com/wp-content/uploads/2011/11/chow-finder1.png" rel="lightbox[4264]"><img src="http://blog.jeffdouglas.com/wp-content/uploads/2011/11/chow-finder1.png" alt="" title="chow-finder1" width="200" class="alignleft size-full wp-image-4266" /></a>This is my submission for the <a href="http://veterans2011.linkedin.com/">LinkedIn Veterans Hackday 2011</a>. <a href="http://blog.cloudspokes.com/2011/11/veterans-hackday-2011-get-involved.html">CloudSpokes threw in an extra $100</a> for any member that submitted as an extra incentive. Our members created some pretty cool apps and I&#8217;ll be highlighting them shortly.</p>
<p>Chow Finder is a mobile application for services members to easily locate dining facilities, aka &#8220;chow halls&#8221;, on any military installation. It was inspired by my sons in the Army and Navy who are always looking for their next meal.</p>
<p>The application was written using <a href="http://jquerymobile.com/">jQuery Mobile</a> and <a href="http://rubyonrails.org/">Ruby on Rails</a>. I used <a href="http://database.com">Database.com</a> for the data store and it is hosted on <a href="http://www.heroku.com">Heroku</a>. All of this for free!</p>

<div class="ngg-galleryoverview" id="ngg-gallery-2-4264">

	<!-- Slideshow link -->
	<div class="slideshowlink">
		<a class="slideshowlink" href="http://blog.jeffdouglas.com/2011/11/15/chow-finder/?show=slide">
			[Show as slideshow]		</a>
	</div>

	
	<!-- Thumbnails -->
		
	<div id="ngg-image-9" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://blog.jeffdouglas.com/wp-content/gallery/chow-finder/chow-finder1.png" title=" " class="shutterset_set_2"  rel="lightbox[4264]">
								<img title="chow-finder1" alt="chow-finder1" src="http://blog.jeffdouglas.com/wp-content/gallery/chow-finder/thumbs/thumbs_chow-finder1.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-10" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://blog.jeffdouglas.com/wp-content/gallery/chow-finder/chow-finder2.png" title=" " class="shutterset_set_2"  rel="lightbox[4264]">
								<img title="chow-finder2" alt="chow-finder2" src="http://blog.jeffdouglas.com/wp-content/gallery/chow-finder/thumbs/thumbs_chow-finder2.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-11" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://blog.jeffdouglas.com/wp-content/gallery/chow-finder/chow-finder3.png" title=" " class="shutterset_set_2"  rel="lightbox[4264]">
								<img title="chow-finder3" alt="chow-finder3" src="http://blog.jeffdouglas.com/wp-content/gallery/chow-finder/thumbs/thumbs_chow-finder3.png" width="100" height="75" />
							</a>
		</div>
	</div>
	
		
 	 	
	<!-- Pagination -->
 	<div class='ngg-clear'></div>
 	
</div>


<p><br/>You can run the <a href="http://chow-finder.herokuapp.com">Chow Finder here</a> or <a href="https://github.com/jeffdonthemic/Chow-Finder">fork the code at GitHub</a>. I&#8217;m still working on some loose ends.</p>
<p><span class="youtube">
<object width="560" height="340">
<param name="movie" value="http://www.youtube.com/v/eCyVbFne12Q?color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;loop=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0&amp;rel=1&amp;hd=1" />
<param name="allowFullScreen" value="true" />
<embed wmode="opaque" src="http://www.youtube.com/v/eCyVbFne12Q?color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;loop=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0&amp;rel=1&amp;hd=1" type="application/x-shockwave-flash" allowfullscreen="true" width="560" height="340"></embed>
<param name="wmode" value="opaque" />
</object>
</span><p><a href="http://www.youtube.com/watch?v=eCyVbFne12Q&fmt=18">www.youtube.com/watch?v=eCyVbFne12Q</a></p></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2011/11/15/chow-finder/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting Salesforce Field Metadata the Easy Way</title>
		<link>http://blog.jeffdouglas.com/2011/10/20/getting-salesforce-field-metadata-the-easy-way/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=getting-salesforce-field-metadata-the-easy-way</link>
		<comments>http://blog.jeffdouglas.com/2011/10/20/getting-salesforce-field-metadata-the-easy-way/#comments</comments>
		<pubDate>Thu, 20 Oct 2011 18:38:01 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Code Sample]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=4203</guid>
		<description><![CDATA[I&#8217;m working on some of the Apex REST services for our CloudSpokes org and needed some code to fetch field level metadata using Apex Describe. I poked around and realized that there isn&#8217;t really much out there. So I decided to write something up and hopefully people find it useful or instructional. Perhaps it should [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F10%2F20%2Fgetting-salesforce-field-metadata-the-easy-way%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F10%2F20%2Fgetting-salesforce-field-metadata-the-easy-way%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://blog.jeffdouglas.com/wp-content/uploads/2011/10/metadata.png" rel="lightbox[4203]"><img src="http://blog.jeffdouglas.com/wp-content/uploads/2011/10/metadata.png" alt="" title="metadata" width="150" height="183" class="alignleft size-full wp-image-4205" /></a>I&#8217;m working on some of the Apex REST services for our <a href="http://www.cloudspokes.com">CloudSpokes</a> org and needed some code to fetch field level metadata using Apex Describe. I poked around and realized that there isn&#8217;t really much out there. So I decided to write something up and hopefully people find it useful or instructional. Perhaps it should be part of <a href="http://code.google.com/p/apex-lang/">apex-lang</a>? </p>
<p>If you&#8217;ve ever worked with Apex Describe before you&#8217;ll quickly realize that it&#8217;s not the easiest thing to work with. You&#8217;ll want to <a href="http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_fields_describe.htm">take a peek at the docs</a>. Don&#8217;t get me wrong, it&#8217;s power, fast and very handy. But it is rather confusing and cumbersome to work with at first. So I wanted some code that returns the metadata for specific fields in an object so that I could look at field types and lengths and perform &#8220;stuff&#8221; accordingly. </p>
<p>So here&#8217;s what I can up with. You pass the method the DescribeFieldResult for an object and a collection of fields that you want metadata for. The method returns a map where the field names are the keys and the values contain the metadata for the corresponding field. It looks pretty hard but that&#8217;s the great thing about utility methods, they encapsulate and hide the complexity of the implementation.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">public static Map&lt;String, Schema.DescribeFieldResult&gt; getFieldMetaData(
  Schema.DescribeSObjectResult dsor, Set&lt;String&gt; fields) {
&nbsp;
  // the map to be returned with the final data
  Map&lt;String,Schema.DescribeFieldResult&gt; finalMap = 
    new Map&lt;String, Schema.DescribeFieldResult&gt;();
  // map of all fields in the object
  Map&lt;String, Schema.SObjectField&gt; objectFields = dsor.fields.getMap();
&nbsp;
  // iterate over the requested fields and get the describe info for each one. 
  // add it to a map with field name as key
  for(String field : fields){
    // skip fields that are not part of the object
    if (objectFields.containsKey(field)) {
      Schema.DescribeFieldResult dr = objectFields.get(field).getDescribe();
      // add the results to the map to be returned
      finalMap.put(field, dr); 
    }
  }
  return finalMap;
}</pre></td></tr></table></div>

<p>So now in my code I can call this static method in my Utils class and access the field metadata easily by fetching it from the map by it&#8217;s field name:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">// field to return -- skips fields not actually part of the sobject
Set&lt;String&gt; fields = new Set&lt;String&gt;{'name','annualrevenue','BADFIELD'};
&nbsp;
Map&lt;String, Schema.DescribeFieldResult&gt; finalMap = 
  Utils.getFieldMetaData(Account.getSObjectType().getDescribe(), fields);
&nbsp;
// only print out the 'good' fields
for (String field : new Set&lt;String&gt;{'name','annualrevenue'}) {
  System.debug(finalMap.get(field).getName()); // field name
  System.debug(finalMap.get(field).getType()); // field type
  System.debug(finalMap.get(field).getLength()); // field length
}</pre></td></tr></table></div>

<p>So if you run this, you&#8217;ll see something like:</p>
<p>DEBUG|Name<br />
DEBUG|STRING<br />
DEBUG|255<br />
DEBUG|AnnualRevenue<br />
DEBUG|CURRENCY<br />
DEBUG|0</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2011/10/20/getting-salesforce-field-metadata-the-easy-way/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Salesforce Trigger when Rollups Summaries Not Possible</title>
		<link>http://blog.jeffdouglas.com/2011/08/23/salesforce-trigger-when-rollups-summaries-not-possible/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=salesforce-trigger-when-rollups-summaries-not-possible</link>
		<comments>http://blog.jeffdouglas.com/2011/08/23/salesforce-trigger-when-rollups-summaries-not-possible/#comments</comments>
		<pubDate>Tue, 23 Aug 2011 11:15:31 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Apex]]></category>
		<category><![CDATA[Code Sample]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=4118</guid>
		<description><![CDATA[Master-Details relationships in Force.com  are very handy but don&#8217;t fit every scenario. For instance, it&#8217;s not possible to implement a rollup summary on formula field or text fields. Here&#8217;s a small trigger that you can use for a starter for these types of situations. The code for each class is available at GitHub for your [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F08%2F23%2Fsalesforce-trigger-when-rollups-summaries-not-possible%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F08%2F23%2Fsalesforce-trigger-when-rollups-summaries-not-possible%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://www.salesforce.com/us/developer/docs/api/Content/relationships_among_objects.htm">Master-Details relationships</a> in Force.com  are very handy but don&#8217;t fit every scenario. For instance, it&#8217;s not possible to implement a rollup summary on formula field or text fields. Here&#8217;s a small trigger that you can use for a starter for these types of situations. The code for each class is available at <a href="https://github.com/jeffdonthemic/Blog-Sample-Code">GitHub</a> for your forking pleasure.</p>
<p>So here&#8217;s the (not very useful) use case. Sales Order is the Master object which can have multiple Sales Order Items (detail object). The Sales Order Item has a &#8220;primary&#8221; Boolean field and a &#8220;purchased country&#8221; field. Each time Sales Order Items are inserted or updated, if the Sales Order Item is marked as &#8220;primary&#8221; then the value of &#8220;purchased country&#8221; is written into the &#8220;primary country&#8221; field on the Sales Order. I&#8217;m assuming that there can only be one Sales Order Item per Sales Order that is marked as primary. Essentially this is just a quick reference on the Sales Order to see which country is primary on any of the multiple Sales Order Items. Not very useful but illustrative.</p>
<p><a href="http://blog.jeffdouglas.com/wp-content/uploads/2011/08/sales-order-item.png" rel="lightbox[4118]"><img src="http://blog.jeffdouglas.com/wp-content/uploads/2011/08/sales-order-item.png" alt="" title="sales-order-item" width="500" class="aligncenter size-full wp-image-4121" /></a></p>
<p>The code is broken down into a Trigger and an Apex &#8220;handler&#8221; class that implements the actual functionality. It&#8217;s <a href="http://blog.jeffdouglas.com/2010/10/21/force-com-programming-best-practices/">best practice</a> to only have one trigger for each object and to avoid complex logic in triggers. To simplify testing and resuse, triggers should delegate to Apex classes which contain the actual execution logic. See <a href="http://www.embracingthecloud.com/2010/07/08/ASimpleTriggerTemplateForSalesforce.aspx">Mike Leach’s excellent trigger template</a> for more info.</p>
<p><strong>SalesOrderItemTrigger</strong> (<a href="https://github.com/jeffdonthemic/Blog-Sample-Code/blob/master/salesforce/src/triggers/SalesOrderItemTrigger.trigger">source on GitHub</a>) - Implements trigger functionality for Sales Order Items. Delegates responsibility to SalesOrderItemTriggerHandler.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">trigger SalesOrderItemTrigger on Sales_Order_Item__c (after insert, after update) {
&nbsp;
  SalesOrderItemTriggerHandler handler = new SalesOrderItemTriggerHandler();
&nbsp;
  if(Trigger.isInsert &amp;&amp; Trigger.isAfter) {
    handler.OnAfterInsert(Trigger.new);
&nbsp;
  } else if(Trigger.isUpdate &amp;&amp; Trigger.isAfter) { 
    handler.OnAfterUpdate(Trigger.old, Trigger.new, Trigger.oldMap, Trigger.newMap);
&nbsp;
  }
&nbsp;
}</pre></td></tr></table></div>

</p>
<p><strong>SalesOrderItemTriggerHandler</strong> (<a href="https://github.com/jeffdonthemic/Blog-Sample-Code/blob/master/salesforce/src/classes/SalesOrderItemTriggerHandler.cls">source on GitHub</a>) - Implements the functionality for the sales order item trigger after insert and after update. Looks at each sales order item and if it is marked as primary_item__c then moves the primary_country__c value from the sales order item to the associated sales order&#8217;s primary_country__c field.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">public with sharing class SalesOrderItemTriggerHandler {
&nbsp;
  // update the primary country when new records are inserted from trigger
  public void OnAfterInsert(List&lt;Sales_Order_Item__c&gt; newRecords){
    updatePrimaryCountry(newRecords); 
  }
&nbsp;
  // update the primary country when records are updated from trigger  
  public void OnAfterUpdate(List&lt;Sales_Order_Item__c&gt; oldRecords, 
      List&lt;Sales_Order_Item__c&gt; updatedRecords,  Map&lt;ID, Sales_Order_Item__c&gt; oldMap, 
      Map&lt;ID, Sales_Order_Item__c&gt; newMap){
    updatePrimaryCountry(updatedRecords); 
  }
&nbsp;
  // updates the sales order with the primary purchased country for the item
  private void updatePrimaryCountry(List&lt;Sales_Order_Item__c&gt; newRecords) {
&nbsp;
    // create a new map to hold the sales order id / country values
    Map&lt;ID,String&gt; salesOrderCountryMap = new Map&lt;ID,String&gt;();
&nbsp;
    // if an item is marked as primary, add the purchased country
    // to the map where the sales order id is the key 
    for (Sales_Order_Item__c soi : newRecords) {
      if (soi.Primary_Item__c)
        salesOrderCountryMap.put(soi.Sales_Order__c,soi.Purchased_Country__c);
    } 
&nbsp;
    // query for the sale orders in the context to update
    List&lt;Sales_Order__c&gt; orders = [select id, Primary_Country__c from Sales_Order__c 
      where id IN :salesOrderCountryMap.keyset()];
&nbsp;
    // add the primary country to the sales order. find it in the map
    // using the sales order's id as the key
    for (Sales_Order__c so : orders)
      so.Primary_Country__c = salesOrderCountryMap.get(so.id);
&nbsp;
    // commit the records 
    update orders;
&nbsp;
  }
&nbsp;
}</pre></td></tr></table></div>

</p>
<p><strong>Test_SalesOrderItemTriggerHandler</strong> (<a href="https://github.com/jeffdonthemic/Blog-Sample-Code/blob/master/salesforce/src/classes/Test_SalesOrderItemTriggerHandler.cls">source on GitHub</a>) - Test class for SalesOrderItemTrigger and SalesOrderItemTriggerHandler. Achieves 100% code coverage.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">@isTest
private class Test_SalesOrderItemTriggerHandler {
&nbsp;
  private static Sales_Order__c so1;
  private static Sales_Order__c so2;
&nbsp;
  // set up our data for each test method
  static {
&nbsp;
  	Contact c = new Contact(firstname='test',lastname='test',email='no@email.com');
  	insert c;
&nbsp;
    so1 = new Sales_Order__c(name='test1',Delivery_Name__c=c.id);
    so2 = new Sales_Order__c(name='test2',Delivery_Name__c=c.id);
&nbsp;
    insert new List&lt;Sales_Order__c&gt;{so1,so2};
&nbsp;
  }
&nbsp;
  static testMethod void testNewRecords() {
&nbsp;
    Sales_Order_Item__c soi1 = new Sales_Order_Item__c();
    soi1.Sales_Order__c = so1.id;
    soi1.Quantity__c = 1;
    soi1.Description__c = 'test';
    soi1.Purchased_Country__c = 'Germany';
&nbsp;
    Sales_Order_Item__c soi2 = new Sales_Order_Item__c();
    soi2.Sales_Order__c = so1.id;
    soi2.Quantity__c = 1;
    soi2.Description__c = 'test';
    soi2.Purchased_Country__c = 'France';
    soi2.Primary_Item__c = true;
&nbsp;
    Sales_Order_Item__c soi3 = new Sales_Order_Item__c();
    soi3.Sales_Order__c = so2.id;
    soi3.Quantity__c = 1;
    soi3.Description__c = 'test';
    soi3.Purchased_Country__c = 'Germany';
    soi3.Primary_Item__c = true;
&nbsp;
    Sales_Order_Item__c soi4 = new Sales_Order_Item__c();
    soi4.Sales_Order__c = so2.id;
    soi4.Quantity__c = 1;
    soi4.Description__c = 'test';
    soi4.Purchased_Country__c = 'Germany';
&nbsp;
    Sales_Order_Item__c soi5 = new Sales_Order_Item__c();
    soi5.Sales_Order__c = so2.id;
    soi5.Quantity__c = 1;
    soi5.Description__c = 'test';
    soi5.Purchased_Country__c = 'Italy';
&nbsp;
    insert new List&lt;Sales_Order_Item__c&gt;{soi1,soi2,soi3,soi4,soi5}; 
&nbsp;
    System.assertEquals(2,[select count() from Sales_Order_Item__c where Sales_Order__c = :so1.id]);
    System.assertEquals(3,[select count() from Sales_Order_Item__c where Sales_Order__c = :so2.id]); 
&nbsp;
    System.assertEquals('France',[select primary_country__c from Sales_Order__c where id = :so1.id].primary_country__c);
    System.assertEquals('Germany',[select primary_country__c from Sales_Order__c where id = :so2.id].primary_country__c);
&nbsp;
  }
&nbsp;
  static testMethod void testUpdatedRecords() {
&nbsp;
    Sales_Order_Item__c soi1 = new Sales_Order_Item__c();
    soi1.Sales_Order__c = so1.id;
    soi1.Quantity__c = 1;
    soi1.Description__c = 'test';
    soi1.Purchased_Country__c = 'Germany';
&nbsp;
    Sales_Order_Item__c soi2 = new Sales_Order_Item__c();
    soi2.Sales_Order__c = so1.id;
    soi2.Quantity__c = 1;
    soi2.Description__c = 'test';
    soi2.Purchased_Country__c = 'France';
    soi2.Primary_Item__c = true;
&nbsp;
    insert new List&lt;Sales_Order_Item__c&gt;{soi1,soi2}; 
&nbsp;
    // assert that the country = France
    System.assertEquals('France',[select primary_country__c from Sales_Order__c where id = :so1.id].primary_country__c);
&nbsp;
    List&lt;Sales_Order_Item__c&gt; items = [select id, purchased_country__c from Sales_Order_Item__c 
      where Sales_Order__c = :so1.id and primary_item__c = true];
    // change the primary country on the sales order item. should trigger update
    items.get(0).purchased_country__c = 'Denmark';
&nbsp;
    update items;
    // assert that the country was successfully changed to Denmark
    System.assertEquals('Denmark',[select primary_country__c from Sales_Order__c where id = :so1.id].primary_country__c);
&nbsp;
  }
&nbsp;
}</pre></td></tr></table></div>
</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2011/08/23/salesforce-trigger-when-rollups-summaries-not-possible/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Demo App &#8211; Ruby, Rails &amp; Force.com REST API on Heroku</title>
		<link>http://blog.jeffdouglas.com/2011/05/31/telesales-rails-heroku/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=telesales-rails-heroku</link>
		<comments>http://blog.jeffdouglas.com/2011/05/31/telesales-rails-heroku/#comments</comments>
		<pubDate>Tue, 31 May 2011 17:30:30 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Code Sample]]></category>
		<category><![CDATA[Heroku]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=3922</guid>
		<description><![CDATA[So continuing with my learning Ruby series, I finally finished my sample app using the Force.com REST API. I ran into a few issues and fortunately Quinton Wall and Heroku support came to my rescue. Apparently require &#8216;Accounts&#8217; and require &#8216;accounts&#8217; aren&#8217;t the same when running on Heroku. Go figure. This is a demo Rails [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F05%2F31%2Ftelesales-rails-heroku%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F05%2F31%2Ftelesales-rails-heroku%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><a href="http://blog.jeffdouglas.com/wp-content/uploads/2011/05/ruby.png" rel="lightbox[3922]"><img src="http://blog.jeffdouglas.com/wp-content/uploads/2011/05/ruby-150x150.png" alt="" title="ruby" width="150" height="150" class="alignleft size-thumbnail wp-image-3927" /></a>So continuing with my <a href="http://blog.jeffdouglas.com/category/ruby/">learning Ruby series</a>, I finally finished my sample app using the Force.com REST API. I ran into a <a href="http://boards.developerforce.com/t5/Perl-PHP-Python-Ruby-Development/Heroku-Crash-No-such-file-to-load-Accounts/td-p/275949">few issues</a> and fortunately <a href="http://twitter.com/quintonwall">Quinton Wall</a> and Heroku support came to my rescue. Apparently <em>require &#8216;Accounts&#8217;</em> and <em>require &#8216;accounts&#8217;</em> aren&#8217;t the same when running on Heroku. Go figure.</p>
<p>This is a demo Rails app running on Ruby 1.9.2 and Rails 3.0.5 hosted on Heroku. It uses OAuth2 via <a href="https://github.com/intridea/omniauth">OmniAuth</a>  to authorize access to a salesforce.com org. It uses the <a href="http://wiki.developerforce.com/index.php/Getting_Started_with_the_Force.com_REST_API">Force.com REST API</a> to query for records, retreive records to display, create new records and update existing ones. It should be good sample app to get noobs (like me) up and running.</p>
<p>I forked Quinton Wall&#8217;s (excellent) <a href="https://github.com/quintonwall/omniauth-rails3-forcedotcom/wiki/Build-Mobile-Apps-in-the-Cloud-with-Omniauth,-Httparty-and-Force.com">omniauth-rails3-forcedotcom project</a> to get started. One of the things you have to do when using the Force.com REST API is to configure your server to run under SSL using WEBrick. I found some excellent instruction for OS X <a href="http://www.nearinfinity.com/blogs/chris_rohr/configuring_webrick_to_use_ssl.html">here</a>.  </p>
<p><a href="https://telesales-rails.heroku.com/" target="_blank" style="font-size: 14pt; font-weight:strong">You can run the app for yourself here.</a></p>
<p>All of the <a href="https://github.com/jeffdonthemic/Telesales-Rails">code for this app is hosted at github</a> so feel free to fork it. I&#8217;ve pulled out some of the more important parts of the app for discussion after the video.</p>
<p><span class="youtube">
<object width="560" height="340">
<param name="movie" value="http://www.youtube.com/v/fRAaodh9jxQ?color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;loop=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0&amp;rel=1&amp;hd=1" />
<param name="allowFullScreen" value="true" />
<embed wmode="opaque" src="http://www.youtube.com/v/fRAaodh9jxQ?color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;loop=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0&amp;rel=1&amp;hd=1" type="application/x-shockwave-flash" allowfullscreen="true" width="560" height="340"></embed>
<param name="wmode" value="opaque" />
</object>
</span><p><a href="http://www.youtube.com/watch?v=fRAaodh9jxQ&fmt=18">www.youtube.com/watch?v=fRAaodh9jxQ</a></p></p>
<p><strong>app/controllers/accounts_controller.rb</strong></p>
<p>The account controller delegates authority to accounts.rb for integration with Force.com and then packages up the returns for the views.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'accounts'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> AccountsController <span style="color:#006600; font-weight:bold;">&lt;</span> ApplicationController
  <span style="color:#9966CC; font-weight:bold;">def</span> index
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> search
    <span style="color:#0066ff; font-weight:bold;">@json</span> = Accounts.<span style="color:#9900CC;">search</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:accountName</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> show
    <span style="color:#0066ff; font-weight:bold;">@account</span> = Accounts.<span style="color:#9900CC;">retrieve</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@opportunities</span> = Accounts.<span style="color:#9900CC;">opportunities</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>    
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> create
     <span style="color:#0066ff; font-weight:bold;">@account</span> = Accounts.<span style="color:#9900CC;">create</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> edit
     <span style="color:#0066ff; font-weight:bold;">@account</span> = Accounts.<span style="color:#9900CC;">retrieve</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> save
    Accounts.<span style="color:#9900CC;">save</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#41;</span>
    redirect_to <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:show</span>, <span style="color:#ff3333; font-weight:bold;">:id</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>  
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> new_opp 
    <span style="color:#0066ff; font-weight:bold;">@account</span> = Accounts.<span style="color:#9900CC;">retrieve</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> save_opp
    Accounts.<span style="color:#9900CC;">create_opp</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#41;</span>
    redirect_to <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:show</span>, <span style="color:#ff3333; font-weight:bold;">:id</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p><strong>lib/accounts.rb</strong></p>
<p>Accounts.rb does most of the heavy lifting for the app. It prepares the requests to Force.com with the correct headers and makes the actual calls to Force.com with the REST API.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'httparty'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Accounts
  <span style="color:#9966CC; font-weight:bold;">include</span> HTTParty
  <span style="color:#008000; font-style:italic;">#doesn't seem to pick up env variable correctly if I set it here</span>
  <span style="color:#008000; font-style:italic;">#headers 'Authorization' =&gt; &quot;OAuth #{ENV['sfdc_token']}&quot;</span>
  <span style="color:#CC0066; font-weight:bold;">format</span> <span style="color:#ff3333; font-weight:bold;">:json</span>
  <span style="color:#008000; font-style:italic;"># debug_output $stderr</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">set_headers</span>
    headers <span style="color:#996600;">'Authorization'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;OAuth #{ENV['sfdc_token']}&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">root_url</span>
    <span style="color:#0066ff; font-weight:bold;">@root_url</span> = ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'sfdc_instance_url'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">+</span><span style="color:#996600;">&quot;/services/data/v&quot;</span><span style="color:#006600; font-weight:bold;">+</span>ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'sfdc_api_version'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">search</span><span style="color:#006600; font-weight:bold;">&#40;</span>keyword<span style="color:#006600; font-weight:bold;">&#41;</span>
    Accounts.<span style="color:#9900CC;">set_headers</span>
    soql = <span style="color:#996600;">&quot;SELECT Id, Name, BillingCity, BillingState, Phone from Account Where Name = <span style="color:#000099;">\'</span>#{keyword}<span style="color:#000099;">\'</span>&quot;</span>
    get<span style="color:#006600; font-weight:bold;">&#40;</span>Accounts.<span style="color:#9900CC;">root_url</span><span style="color:#006600; font-weight:bold;">+</span><span style="color:#996600;">&quot;/query/?q=#{CGI::escape(soql)}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    Accounts.<span style="color:#9900CC;">set_headers</span>
    headers <span style="color:#996600;">'Content-Type'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;application/json&quot;</span>
&nbsp;
    options = <span style="color:#006600; font-weight:bold;">&#123;</span>
      <span style="color:#ff3333; font-weight:bold;">:body</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
          <span style="color:#ff3333; font-weight:bold;">:Name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;1234&quot;</span>
      <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">to_json</span>
    <span style="color:#006600; font-weight:bold;">&#125;</span>
    response = post<span style="color:#006600; font-weight:bold;">&#40;</span>Accounts.<span style="color:#9900CC;">root_url</span><span style="color:#006600; font-weight:bold;">+</span><span style="color:#996600;">&quot;/sobjects/Account/&quot;</span>, options<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;"># puts response.body, response.code, response.message</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">save</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#41;</span>
    Accounts.<span style="color:#9900CC;">set_headers</span>
    headers <span style="color:#996600;">'Content-Type'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;application/json&quot;</span>
&nbsp;
    options = <span style="color:#006600; font-weight:bold;">&#123;</span>
      <span style="color:#ff3333; font-weight:bold;">:body</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
          <span style="color:#ff3333; font-weight:bold;">:billingcity</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:BillingCity</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">to_json</span>
    <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#CC0066; font-weight:bold;">p</span> options
    response = post<span style="color:#006600; font-weight:bold;">&#40;</span>Accounts.<span style="color:#9900CC;">root_url</span><span style="color:#006600; font-weight:bold;">+</span><span style="color:#996600;">&quot;/sobjects/Account/#{params[:id]}?_HttpMethod=PATCH&quot;</span>, options<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;"># 201 response.body equals success</span>
    <span style="color:#008000; font-style:italic;"># puts response.body, response.code, response.message</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">retrieve</span><span style="color:#006600; font-weight:bold;">&#40;</span>id<span style="color:#006600; font-weight:bold;">&#41;</span>
    Accounts.<span style="color:#9900CC;">set_headers</span>
    get<span style="color:#006600; font-weight:bold;">&#40;</span>Accounts.<span style="color:#9900CC;">root_url</span><span style="color:#006600; font-weight:bold;">+</span><span style="color:#996600;">&quot;/sobjects/Account/#{id}?fields=Id,Name,BillingCity,BillingState,Phone,Website&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> 
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">opportunities</span><span style="color:#006600; font-weight:bold;">&#40;</span>accountId<span style="color:#006600; font-weight:bold;">&#41;</span>
    Accounts.<span style="color:#9900CC;">set_headers</span>
    soql = <span style="color:#996600;">&quot;SELECT Id, Name, Amount, StageName, Probability, CloseDate from Opportunity where AccountId = <span style="color:#000099;">\'</span>#{accountId}<span style="color:#000099;">\'</span>&quot;</span>
    get<span style="color:#006600; font-weight:bold;">&#40;</span>Accounts.<span style="color:#9900CC;">root_url</span><span style="color:#006600; font-weight:bold;">+</span><span style="color:#996600;">&quot;/query/?q=#{CGI::escape(soql)}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">create_opp</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#41;</span>
    Accounts.<span style="color:#9900CC;">set_headers</span>
    headers <span style="color:#996600;">'Content-Type'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;application/json&quot;</span>
&nbsp;
    options = <span style="color:#006600; font-weight:bold;">&#123;</span>
      <span style="color:#ff3333; font-weight:bold;">:body</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
          <span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:name</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
          <span style="color:#ff3333; font-weight:bold;">:amount</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:amount</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
          <span style="color:#ff3333; font-weight:bold;">:accountId</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
          <span style="color:#ff3333; font-weight:bold;">:amount</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:amount</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
          <span style="color:#ff3333; font-weight:bold;">:closeDate</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:closeDate</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
          <span style="color:#ff3333; font-weight:bold;">:stageName</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:stageName</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">to_json</span>
    <span style="color:#006600; font-weight:bold;">&#125;</span>
    response = post<span style="color:#006600; font-weight:bold;">&#40;</span>Accounts.<span style="color:#9900CC;">root_url</span><span style="color:#006600; font-weight:bold;">+</span><span style="color:#996600;">&quot;/sobjects/Opportunity/&quot;</span>, options<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;"># 201 response.body equals success</span>
    <span style="color:#008000; font-style:italic;"># puts response.body, response.code, response.message</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p><strong>app/views/search.html.erb</strong></p>
<p>The search view allows the user to search for an account and display the results.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">&lt;span class=&quot;title&quot;&gt;Welcome to the ACME Telesales Application (RoR on Heroku)&lt;/span&gt;&lt;p/&gt;
&lt;p&gt;This demo shows you how to query, retrieve, create and edit records in salesforce.com.&lt;/p&gt;
&lt;p&gt;Search for an Account to view all of its Opportunities or to create a new one.&lt;/p&gt;
&lt;p/&gt;
&lt;form method=&quot;post&quot; action=&quot;search&quot;&gt;
  &lt;span class=&quot;heading&quot;&gt;Search by Account Name:&lt;/span&gt;&lt;p/&gt;
  &lt;input type=&quot;text&quot; name=&quot;accountName&quot; value=&quot;<span style="color:#006600; font-weight:bold;">&lt;%</span>= params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:accountName</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&quot; style=&quot;width: 300px&quot;/&gt;
  &lt;input type=&quot;submit&quot; value=&quot;Search&quot;/&gt;
&lt;/form&gt;
&lt;p/&gt;
&nbsp;
&lt;span class=&quot;heading&quot;&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@json</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;records&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">length</span> <span style="color:#006600; font-weight:bold;">%&gt;</span> accounts matching your search criteria:&lt;/span&gt;
&nbsp;
&lt;p/&gt;
&lt;table border=&quot;0&quot; cellspacing=&quot;1&quot; cellpadding=&quot;5&quot; bgcolor=&quot;#CCCCCC&quot; width=&quot;50%&quot;&gt;
&lt;tr bgcolor=&quot;#407BA8&quot;&gt;
  &lt;td style=&quot;color: #ffffff; font-weight: bold;&quot;&gt;Name&lt;/td&gt;
  &lt;td style=&quot;color: #ffffff; font-weight: bold;&quot;&gt;City&lt;/td&gt;
  &lt;td style=&quot;color: #ffffff; font-weight: bold;&quot;&gt;State&lt;/td&gt;
  &lt;td style=&quot;color: #ffffff; font-weight: bold;&quot;&gt;Phone&lt;/td&gt;
&lt;/tr&gt;
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#0066ff; font-weight:bold;">@json</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;records&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>record<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  &lt;tr style=&quot;background:#ffffff&quot; onMouseOver=&quot;this.style.background='#eeeeee';&quot; onMouseOut=&quot;this.style.background='#ffffff';&quot;&gt;
    &lt;td&gt;&lt;a href=&quot;/accounts/<span style="color:#006600; font-weight:bold;">&lt;%</span>= record<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;Id&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">%&gt;</span>&quot;&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= record<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;Name&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/a&gt;&lt;/td&gt;
    &lt;td&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= record<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;BillingCity&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/td&gt;
    &lt;td&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= record<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;BillingState&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/td&gt;
    &lt;td&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= record<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;Phone&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/td&gt;
  &lt;/tr&gt;
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
&lt;/table&gt;</pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2011/05/31/telesales-rails-heroku/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>OpportunityAccessLevel Not Writable</title>
		<link>http://blog.jeffdouglas.com/2011/03/17/opportunityaccesslevel-not-writable/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=opportunityaccesslevel-not-writable</link>
		<comments>http://blog.jeffdouglas.com/2011/03/17/opportunityaccesslevel-not-writable/#comments</comments>
		<pubDate>Thu, 17 Mar 2011 10:40:44 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Apex]]></category>
		<category><![CDATA[Code Sample]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=3767</guid>
		<description><![CDATA[I was working on a project the other day where I needed to dynamically add users to an opportunity&#8217;s Sales Team (OpportunityTeamMember object) so that users who do not normally have access to an opportunity based upon Org-wide security settings can work on the opportunity with other team members. One of the advantages of Sales [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F03%2F17%2Fopportunityaccesslevel-not-writable%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F03%2F17%2Fopportunityaccesslevel-not-writable%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I was working on a project the other day where I needed to dynamically add users to an opportunity&#8217;s Sales Team (OpportunityTeamMember object) so that users who do not normally have access to an opportunity based upon Org-wide security settings can work on the opportunity with other team members. One of the advantages of Sales Teams is that you can specify the level of access that each team member has for the opportunity. Some team members may need read/write access while others may just need read-only access.</p>
<p>From the opportunity page layout you can add a new team member and specify their access level and role.</p>
<p><img title="sales-team.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2011/03/sales-team.png" border="0" alt="Sales team" width="500" height="186" /></p>
<p>However, by default when you create a new team member via Apex, the platform grants them read-only access. So I tried to specify grant &#8220;Edit&#8221; (read/write) access with the following code.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">OpportunityTeamMember member = new OpportunityTeamMember();
member.OpportunityId = SomeOpp.Id;
member.UserId = SomeUser.Id;
mmember.TeamMemberRole = 'Sales Rep';
member.OpportunityAccessLevel = 'Edit';</pre></td></tr></table></div>

</p>
<p>Specifying the OpportunityAccessLevel threw the following error when saving my class:</p>
<blockquote><p>Save error: Field is not writable: OpportunityTeamMember.OpportunityAccessLevel</p></blockquote>
<p>To be fair, <a href="http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_objects_opportunityteammember.htm" target="_blank">the docs</a> state that OpportunityAccessLevel is not creatable but it used to be with earlier versions of the API so I <em><strong>really</strong></em> wanted this to work and it was screwing up my day.</p>
<p>So here&#8217;s the solution that I can up with in case anyone is looking for a answers. You need to add the team members to the opportunity and then update the sharing access to the opportunity for these users.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">OpportunityTeamMember member = new OpportunityTeamMember();
member.OpportunityId = SomeOpp.Id;
member.UserId = SomeUser.Id;
mmember.TeamMemberRole = 'Sales Rep';
&nbsp;
insert member;
&nbsp;
// get all of the team members' sharing records
List&lt;OpportunityShare&gt; shares = [select Id, OpportunityAccessLevel, 
  RowCause from OpportunityShare where OpportunityId IN :SomeSetOfOpptyIds 
  and RowCause = 'Team'];
&nbsp;
// set all team members access to read/write
for (OpportunityShare share : shares) 
  share.OpportunityAccessLevel = 'Edit';
&nbsp;
update shares;</pre></td></tr></table></div>
</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2011/03/17/opportunityaccesslevel-not-writable/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Dynamically Group &amp; Display Query Results</title>
		<link>http://blog.jeffdouglas.com/2011/03/02/dynamically-group-display-query-results/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=dynamically-group-display-query-results</link>
		<comments>http://blog.jeffdouglas.com/2011/03/02/dynamically-group-display-query-results/#comments</comments>
		<pubDate>Wed, 02 Mar 2011 10:55:14 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Apex]]></category>
		<category><![CDATA[Code Sample]]></category>
		<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[Visualforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=3737</guid>
		<description><![CDATA[I was working on a Visualforce page that displays the results of a query in separate PageBlock sections based upon a value in the query results. I ran into a small issue which took about an hour or so to solve, so I thought it might make descent blog fodder. The requirement for the page [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F03%2F02%2Fdynamically-group-display-query-results%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F03%2F02%2Fdynamically-group-display-query-results%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I was working on a Visualforce page that displays the results of a query in separate PageBlock sections based upon a value in the query results. I ran into a small issue which took about an hour or so to solve, so I thought it might make descent blog fodder. </p>
<p>The requirement for the page was to query for records and then display them grouped in sections in a Visualforce page based upon whatever values (in this case BillingState) are returned in the results. If additional states were added, then the Visualforce page should be able to add those new sections without changes to the code. Here&#8217;s a screenshot of the sample solution that I came up with but you can also<a href="http://jeffdouglas-developer-edition.na5.force.com/examples/DisplaySections" target="_blank"> run this sample on my Developer Site</a>:</p>
<p><a href="http://blog.jeffdouglas.com/wp-content/uploads/2011/03/group-by-value.png" rel="lightbox[3737]"><img src="http://blog.jeffdouglas.com/wp-content/uploads/2011/03/group-by-value-300x283.png" alt="" title="group-by-value" width="300" height="283" class="alignnone size-medium wp-image-3738" /></a></p>
<p>Here&#8217;s the code for the Visualforce page. I&#8217;ve made it as bare as possible but you can see that it iterates over the array of states to display the pageBlock sections and then displays the record if the state matches the current blockSection&#8217;s state.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">&lt;apex:page controller=&quot;DisplaySectionsController&quot; action=&quot;{!load}&quot; sidebar=&quot;false&quot;&gt;
  &lt;apex:sectionHeader title=&quot;My Sample Display Page&quot; subtitle=&quot;Group by States&quot; 
    description=&quot;This page shows how you can dynamically group results by field value.&quot;/&gt;
&nbsp;
  &lt;apex:repeat value=&quot;{!states}&quot; var=&quot;state&quot;&gt;
&nbsp;
    &lt;apex:pageBlock title=&quot;{!state}&quot;&gt;
&nbsp;
      &lt;apex:repeat value=&quot;{!accounts}&quot; var=&quot;account&quot;&gt; 
&nbsp;
        &lt;apex:outputPanel rendered=&quot;{!IF(state=account.BillingState,true,false)}&quot;&gt;
        {!account.Name} - {!account.BillingState}&lt;br/&gt;
        &lt;/apex:outputPanel&gt;
&nbsp;
      &lt;/apex:repeat&gt;
&nbsp;
    &lt;/apex:pageBlock&gt;
&nbsp;
  &lt;/apex:repeat&gt;
&nbsp;
&lt;/apex:page&gt;</pre></td></tr></table></div>

<p>The Controller exposes two collections to the Visualforce page: the list of Accounts and the array of States.  Here&#8217;s the issue that I ran into. Since I wanted to have a collection of unique state names, I originally added each state to a Set and simply returned the Set to the Visualforce page (instead of the array) to display the pageBlock sections. However, returning the Set gave me a compile error at line 11 in the Visualforce page:</p>
<blockquote><p>Save error: Incorrect parameter for operator &#8216;=&#8217;. Expected Text, received Object</p></blockquote>
<p>The problem is that even though the Set is a collection of Strings, it is actually an object underneath the covers and throws a comparison error. Therefore you have to return the states as an array of strings for the code to compile and run properly.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">public with sharing class DisplaySectionsController {
&nbsp;
  public List&lt;Account&gt; accounts {get;set;}  
  public String[] states {get;set;}
&nbsp;
  public void load() {
&nbsp;
    // for demo purposes limit the states  
    accounts = [Select ID, Name, BillingState From Account 
      Where BillingState IN ('CA','NY','FL')];
&nbsp;
    // dynamically create set of unique states from query
    Set&lt;String&gt; stateSet = new Set&lt;String&gt;();
    for (Account a : accounts)
      stateSet.add(a.BillingState);
&nbsp;
    // convert the set into a string array  
    states = new String[stateSet.size()];
    Integer i = 0;
    for (String state : stateSet) { 
      states[i] = state;
      i++;
    }
&nbsp;
  }
&nbsp;
}</pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2011/03/02/dynamically-group-display-query-results/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Find My Salesforce Users by Role Hierarchy</title>
		<link>http://blog.jeffdouglas.com/2011/02/15/find-my-salesforce-users-by-role-hierarchy/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=find-my-salesforce-users-by-role-hierarchy</link>
		<comments>http://blog.jeffdouglas.com/2011/02/15/find-my-salesforce-users-by-role-hierarchy/#comments</comments>
		<pubDate>Tue, 15 Feb 2011 19:28:28 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Code Sample]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=3678</guid>
		<description><![CDATA[This is a cool little script that finds &#8220;everyone who works beneath me in the role hierarchy&#8221;. So you pass the utility class a User ID and it chugs through all of the level beneath that User in the role hierarchy and returns the IDs of all of the users in those roles. Comes in [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F02%2F15%2Ffind-my-salesforce-users-by-role-hierarchy%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F02%2F15%2Ffind-my-salesforce-users-by-role-hierarchy%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>This is a cool little script that finds &#8220;everyone who works beneath me in the role hierarchy&#8221;. So you pass the utility class a User ID and it chugs through all of the level beneath that User in the role hierarchy and returns the IDs of all of the users in those roles. Comes in handy if you need to find all of the uses that report to a particular Sales Manager, for instance.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">public with sharing class RoleUtils {
&nbsp;
  public static Set&lt;ID&gt; getRoleSubordinateUsers(Id userId) {
&nbsp;
    // get requested user's role
    Id roleId = [select UserRoleId from User where Id = :userId].UserRoleId;
    // get all of the roles underneath the user
    Set&lt;Id&gt; allSubRoleIds = getAllSubRoleIds(new Set&lt;ID&gt;{roleId});
    // get all of the ids for the users in those roles
    Map&lt;Id,User&gt; users = new Map&lt;Id, User&gt;([Select Id, Name From User where 
      UserRoleId IN :allSubRoleIds]);
    // return the ids as a set so you can do what you want with them
    return users.keySet();
&nbsp;
  }
&nbsp;
  private static Set&lt;ID&gt; getAllSubRoleIds(Set&lt;ID&gt; roleIds) {
&nbsp;
    Set&lt;ID&gt; currentRoleIds = new Set&lt;ID&gt;();
&nbsp;
    // get all of the roles underneath the passed roles
    for(UserRole userRole :[select Id from UserRole where ParentRoleId 
      IN :roleIds AND ParentRoleID != null])
    currentRoleIds.add(userRole.Id);
&nbsp;
    // go fetch some more rolls!
    if(currentRoleIds.size() &gt; 0)
      currentRoleIds.addAll(getAllSubRoleIds(currentRoleIds));
&nbsp;
    return currentRoleIds;
&nbsp;
  }
&nbsp;
}</pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2011/02/15/find-my-salesforce-users-by-role-hierarchy/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Learning Ruby for Force.com Developers – Part 3</title>
		<link>http://blog.jeffdouglas.com/2011/02/03/learning-ruby-for-force-com-developers-%e2%80%93-part-3/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=learning-ruby-for-force-com-developers-%25e2%2580%2593-part-3</link>
		<comments>http://blog.jeffdouglas.com/2011/02/03/learning-ruby-for-force-com-developers-%e2%80%93-part-3/#comments</comments>
		<pubDate>Thu, 03 Feb 2011 11:41:43 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Code Sample]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=3608</guid>
		<description><![CDATA[This is part #3 of my adventures of learning Ruby for Force.com developers. If you missed parts #1 and #2 you might want to take a look at those just to get up to speed. Again, these are my goals for this series: Learn Ruby Develop an app locally using Ruby on Rails and the default SQLite [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F02%2F03%2Flearning-ruby-for-force-com-developers-%25e2%2580%2593-part-3%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F02%2F03%2Flearning-ruby-for-force-com-developers-%25e2%2580%2593-part-3%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>This is part #3 of my adventures of learning Ruby for Force.com developers. If you missed parts <a href="http://blog.jeffdouglas.com/2010/12/30/learning-ruby-for-force-com-developers-part-1/">#1</a> and <a href="http://blog.jeffdouglas.com/2011/01/11/learning-ruby-for-force-com-developers-%E2%80%93-part-2/">#2</a> you might want to take a look at those just to get up to speed. Again, these are my goals for this series:</p>
<ul>
<li>Learn Ruby</li>
<li>Develop an app locally using Ruby on Rails and the default SQLite database (this is where we are at right now)</li>
<li>Modify the app to use Database.com and the Force.com Toolkit for Ruby instead of the SQLite database</li>
<li>Deploy the app to <a href="http://heroku.com/">Heroku</a></li>
<li>Modify the app to use Database.com and the REST API</li>
</ul>
<p>In this post we&#8217;ll get started building a web app using Ruby on Rails and SQLite. In a nutshell we&#8217;ll be building a shopping cart app with a little twist. I do a lot of work for <a href="http://www.medisend.org">Medisend International</a>, which is a non-profit that ships medical supplies to developing countries (among other things). They have an (old) international aid self-service portal that allows aid recipients (typically hospital administrators or local NGOs) to create a shipment and select medical supplies to be shipped to their country. We&#8217;ll be building a replacement with Ruby on Rails.</p>
<p>Before you get started you might want to go through <a href="http://guides.rubyonrails.org/getting_started.html">Get Started with Rails</a> which has a lot of great stuff. I&#8217;m only using a subset of the functionality outlined in this guide so you&#8217;ll definitely want to go through this entire article. I&#8217;ll zip up all of the code for this part so you can <a href="http://www.jeffdouglas.com/download/ruby-part3-code.zip">download it</a> and pick it apart.</p>
<p>The first thing we&#8217;ll want to do is install our software needed for Rails. I had some issues during some of the installations but unfortunately I can&#8217;t help out much so hopefully things go well for you. First, open Terminal and run the following lines:</p>
<p style="font-family: 'Lucida Console';"><strong>sudo gem update &#8211;system<br />sudo gem install rails<br />sudo bundle install<br />sudo gem update rake<br />sudo gem update sqlite3-ruby</strong></p>
<p>Now that all of your software is (hopefully) installed let&#8217;s start building the app using SQLite to store data. Open Terminal and change to the directory where you want to store your files (~/Documents/Programming/Ruby in my case) and run the following command to create the application:</p>
<p style="font-family: 'Lucida Console';"><strong>rails new mediaid-sqlite</strong></p>
<p>This will create a Rails application called MediaidSqlite in a directory called mediaid-sqlite. Now switch to this new directory:</p>
<p style="font-family: 'Lucida Console';"><strong>cd mediaid-sqlite</strong></p>
<p>Rails created an entire directory structure for us with all of the files we need to begin building out the app. Feel free to take a look. We&#8217;ll mainly be working in the app directory. Since we&#8217;ll be using SQLite, run the following command to create an empty database:</p>
<p style="font-family: 'Lucida Console';"><strong>rake db:create</strong></p>
<p>This will create both a development and test SQLite databases inside the db/ folder. You now have a fully functional Rails application. To see it in action, fire up the web server on your local development machine by running:</p>
<p style="font-family: 'Lucida Console';"><strong>rails server</strong></p>
<p>If all goes well, when you point your browser to http://localhost:3000 you should see the following:</p>
<p><img title="ruby-part3-welcome.png.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2011/02/ruby-part3-welcome.png.png" border="0" alt="ruby-part3-welcome.png.png" width="550" height="409" /></p>
<p>To stop the web server, simply hit Ctrl+C in the same Terminal window. I typically have at least two Terminal tabs open; one for the server and one for running commands. When running in development mode, Rails does not generally require you to bounce the server when changes are made; changes and files will be automatically picked up by the server.</p>
<p>For the required &#8220;Hello World&#8221; for the home page, you need to create at minimum a controller and a view. Fortunately, you can do that in a single command. Run the following command in Terminal:</p>
<p style="font-family: 'Lucida Console';"><strong>rails generate controller home index</strong></p>
<p>Now we need to delete the default page from your application so Rails will not load it by default. We need to do this as Rails will deliver any static file in the public directory in preference to any dynamic contact we generate from the controllers:</p>
<p style="font-family: 'Lucida Console';"><strong>rm public/index.html</strong></p>
<p>Now, you have to tell Rails where the new home page is located. Open the file config/routes.rb in Textmate or your favorite editor. This is your application’s routing file which holds entries in a special DSL that tells Rails how to route incoming requests to your controllers and actions. This file contains many commented out sample routes, and one of them actually shows you how to connect the root of your site to a specific controller and action. Find the line beginning with <em>:root to</em> towards the end of the file, uncomment it so that is looks like the following:</p>
<p style="font-family: 'Lucida Console';"><strong>root :to =&gt; &#8220;home#index&#8221;</strong></p>
<p>One of the cool thing about Rails is the scaffolding. Rails scaffolding is a quick and easy way to generate some of the major pieces of an application such as models, views, and controllers for a new resource. It provides the basic functionality and UI to CRUD records. We can create the scaffolding for Shipment and InventoryItem with just a few easy commands. The command below creates the scaffolding for the Shipment resource and specifies the fields for the model:</p>
<p style="font-family: 'Lucida Console';"><strong>rails generate scaffold Shipment name:string country:string shipmentType:string status:string shipDate:date items:integer selected:integer reserved:integer</strong></p>
<p>One of the outputs of the rails generate scaffold command is a database migration script. Migrations are Ruby classes that are designed to make it simple to create and modify database tables. Rails uses rake commands to run migrations, and it’s possible to undo a migration after it’s been applied to your database. Migration filenames include a timestamp to ensure that they’re processed in the order that they were created. Now use the following rake command to run the migration:</p>
<p style="font-family: 'Lucida Console';"><strong>rake db:migrate</strong></p>
<p>Now we need the InventoryItems to add to our Shipments. Run the following rails generated scaffold command to create the InventoryItems scaffolding:</p>
<p style="font-family: 'Lucida Console';"><strong>rails generate scaffold InventoryItem name:string itemNumber:string category:string status:string shipment:integer</strong></p>
<p>Now run the rake command to perform the database migration for InventoryItems:</p>
<p style="font-family: 'Lucida Console';"><strong>rake db:migrate</strong></p>
<p>So now we have our database setup and the basic functionality generated for us by Rails. Some people don&#8217;t like the scaffolding and prefer to code from scratch but I&#8217;m going to simply modify the code generated by the scaffolding. The application consists of essentially 6 view and one controller. We&#8217;ll look at the views first and then dig into the controller.</p>
<p><strong>Home Page</strong></p>
<p>The home page displays a summary of the available shipments and allows the user to select a shipment to process. There are also links at the bottom to access the auto-generated UI to CRUD records for both shipments and inventory items.</p>
<p><img title="ruby3-1.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2011/02/ruby3-1.png" border="0" alt="Ruby3 1" width="550" height="347" /></p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;h3&gt;Welcome to MediSend's MediAid!&lt;/h3&gt;
&lt;p&gt;MediAid is an international aid, self-service portal for 
  inventory selection, processing and information centralization.&lt;/p&gt;
&nbsp;
&lt;p&gt;The following shipments are available for your aid case:&lt;/p&gt;
&nbsp;
&lt;table width=&quot;75%&quot; cellpadding=&quot;2&quot; cellspacing=&quot;2&quot;&gt;
&lt;tr&gt;
  &lt;th align=&quot;left&quot;&gt;Shipment&lt;/th&gt;
  &lt;th align=&quot;left&quot;&gt;Type&lt;/th&gt;
  &lt;th align=&quot;left&quot;&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;% @shipments.each do |shipment| %&gt;
&lt;tr&gt;
  &lt;td&gt;&lt;%= link_to shipment.name, shipment %&gt;&lt;/td&gt;
  &lt;td&gt;&lt;%= shipment.shipmentType %&gt;&lt;/td&gt;
  &lt;td&gt;&lt;%= shipment.status %&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;% end %&gt;
&lt;/table&gt;
&nbsp;
&lt;p&gt;&lt;br/&gt;The following options are also available:&lt;/p&gt;
&nbsp;
&lt;ul&gt;
  &lt;li&gt;&lt;%= link_to &quot;Maintain Shipments&quot;, shipments_path %&gt;&lt;/li&gt;
  &lt;li&gt;&lt;%= link_to &quot;Maintain Inventory Items&quot;, inventory_items_path %&gt;&lt;/li&gt;
&lt;/ul&gt;</pre></td></tr></table></div>

</p>
<p><strong>Shipment Display</strong></p>
<p>This page is where most of the work is done for a shipment. It provides the relevant info on the shipment and allows the users to manage the shipment&#8217;s contents.</p>
<p><img title="ruby3-2.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2011/02/ruby3-2.png" border="0" alt="Ruby3 2" width="550" height="347" /></p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">&lt;p id=&quot;notice&quot;&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= notice <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/p&gt;
&nbsp;
&lt;script type=&quot;text/javascript&quot;&gt;
function confirmDelete() {
  var answer = confirm(&quot;Are you sure you want to remove all items from this shipment?&quot;)
  if (answer) window.location = &quot;/shipments/<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">id</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>/remove&quot;;
}
&nbsp;
function confirmReserve() {
  var answer = confirm(&quot;Are you sure you want to update all of the items in this shipment as reserved?&quot;)
  if (answer) window.location = &quot;/shipments/<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">id</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>/reserve&quot;;
}
&lt;/script&gt;
&nbsp;
&lt;h3&gt;Shipment <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">name</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/h3&gt;
&nbsp;
&lt;p&gt;
Status: <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">status</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;br/&gt;
Type: <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">shipmentType</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;br/&gt;
Country: <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">country</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;br/&gt;
Items: <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">items</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;br/&gt;
Selected: <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">selected</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;br/&gt;
Reserved: <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">reserved</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
&lt;/p&gt;
&nbsp;
&lt;p&gt;Available options for this shipment:
&lt;ol&gt;
  &lt;li&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= link_to <span style="color:#996600;">'View items in this shipment'</span>, items_shipment_path<span style="color:#006600; font-weight:bold;">&#40;</span>@shipment<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/li&gt;
  &lt;li&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= link_to <span style="color:#996600;">'Add items by product category to this shipment'</span>, additems_shipment_path<span style="color:#006600; font-weight:bold;">&#40;</span>@shipment<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#&quot; onclick=&quot;return confirmReserve();&quot;&gt;Mark all items as &quot;reserved&quot; for this shipment&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#&quot; onclick=&quot;return confirmDelete();&quot;&gt;Remove all items from this shipment&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= link_to <span style="color:#996600;">'View this shipment<span style="color:#000099;">\'</span>s manifest'</span>, manifest_shipment_path<span style="color:#006600; font-weight:bold;">&#40;</span>@shipment<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/li&gt;
&lt;/ol&gt;
&lt;/p&gt;
&nbsp;
<span style="color:#006600; font-weight:bold;">&lt;%</span>= link_to <span style="color:#996600;">'Edit'</span>, edit_shipment_path<span style="color:#006600; font-weight:bold;">&#40;</span>@shipment<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span> |
<span style="color:#006600; font-weight:bold;">&lt;%</span>= link_to <span style="color:#996600;">'Back'</span>, shipments_path <span style="color:#006600; font-weight:bold;">%&gt;</span></pre></td></tr></table></div>

</p>
<p><strong>Add Inventory Items</strong></p>
<p>The add items pages displays the number of available inventory items by category and if there is at least one available, provides the user with a link to add all of the available items. Clicking the link runs the addAll route to add the items to the shipment and then redirect the user back to the shipment display page.</p>
<p><img title="ruby3-3.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2011/02/ruby3-3.png" border="0" alt="Ruby3 3" width="550" height="347" /></p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">&lt;h3&gt;Add Inventory by Category&lt;/h3&gt;
&nbsp;
&lt;table width=&quot;100%&quot; cellpadding=&quot;2&quot; cellspacing=&quot;2&quot;&gt;
&lt;tr&gt;
  &lt;th align=&quot;left&quot;&gt;Category&lt;/th&gt;
  &lt;th align=&quot;left&quot;&gt;Available&lt;/th&gt;
  &lt;th align=&quot;left&quot;&gt;Add All&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Surgical Gloves&lt;/td&gt;
  &lt;td&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@gloves</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/td&gt;
  &lt;td&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@gloves</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">0</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;a href=&quot;/shipments/<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">id</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>/addAll?category=Gloves&quot;&gt;Add All&lt;/a&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">else</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>Add All<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Nebulizer Accessory Kits&lt;/td&gt;
  &lt;td&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@nebulizer</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/td&gt;
  &lt;td&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@nebulizer</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">0</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;a href=&quot;/shipments/<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">id</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>/addAll?category=Nebulizer&quot;&gt;Add All&lt;/a&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">else</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>Add All<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Hyperinflation Systems&lt;/td&gt;
  &lt;td&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@hyperinflation</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/td&gt;
  &lt;td&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@hyperinflation</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">0</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;a href=&quot;/shipments/<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">id</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>/addAll?category=Hyperinflation&quot;&gt;Add All&lt;/a&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">else</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>Add All<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Breathing Circuits&lt;/td&gt;
  &lt;td&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@circuit</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/td&gt;
  &lt;td&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@circuit</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">0</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;a href=&quot;/shipments/<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">id</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>/addAll?category=Circuits&quot;&gt;Add All&lt;/a&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">else</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>Add All<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Armboards&lt;/td&gt;
  &lt;td&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@armboard</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/td&gt;
  &lt;td&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@armboard</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">0</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;a href=&quot;/shipments/<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">id</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>/addAll?category=Armboards&quot;&gt;Add All&lt;/a&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">else</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>Add All<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&nbsp;
&lt;br/&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= link_to <span style="color:#996600;">'Back'</span>, shipment_path<span style="color:#006600; font-weight:bold;">&#40;</span>@shipment<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span></pre></td></tr></table></div>

</p>
<p><strong>View Shipment Inventory Items</strong></p>
<p>The page simply displays the inventory items currently assigned to this shipment.</p>
<p><img title="ruby3-4.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2011/02/ruby3-4.png" border="0" alt="Ruby3 4" width="550" height="347" /></p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">&lt;h3&gt;Items for Shipment <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">name</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/h3&gt;
&nbsp;
&lt;table width=&quot;100%&quot; cellpadding=&quot;2&quot; cellspacing=&quot;2&quot;&gt;
&lt;tr&gt;
  &lt;th align=&quot;left&quot;&gt;Item&lt;/th&gt;
  &lt;th align=&quot;left&quot;&gt;Name&lt;/th&gt;
  &lt;th align=&quot;left&quot;&gt;Category&lt;/th&gt;
  &lt;th align=&quot;left&quot;&gt;Status&lt;/th&gt;
&lt;/tr&gt;
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#0066ff; font-weight:bold;">@items</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>item<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
&lt;tr&gt;
  &lt;td&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= item.<span style="color:#9900CC;">itemNumber</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/td&gt;
  &lt;td&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= item.<span style="color:#9900CC;">name</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/td&gt;
  &lt;td&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= item.<span style="color:#9900CC;">category</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/td&gt;
  &lt;td&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= item.<span style="color:#9900CC;">status</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/td&gt;
&lt;/tr&gt;
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
&lt;/table&gt;
&nbsp;
&lt;br/&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= link_to <span style="color:#996600;">'Back'</span>, shipment_path<span style="color:#006600; font-weight:bold;">&#40;</span>@shipment<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span></pre></td></tr></table></div>

</p>
<p><strong>Mark Items as Reserved</strong></p>
<p>Items that have been added to the shipment need to be marked as reserved so that they can be processed for shipping. Clicking &#8220;OK&#8221; runs the reserve route to mark the items in the shipment as reserved and then redirect the user back to the shipment display page.</p>
<p><img title="ruby3-5.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2011/02/ruby3-5.png" border="0" alt="Ruby3 5" width="550" height="347" /></p>
<p><strong>Remove Items from Shipment</strong></p>
<p>Users may want to remove all of the items from their shipment and begin the process anew. Clicking &#8220;OK&#8221; runs the remove route which removes all of the items from the shipment, making them available again, and then redirects the user back to the shipment display page.</p>
<p><img title="ruby3-6.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2011/02/ruby3-6.png" border="0" alt="Ruby3 6" width="550" height="347" /></p>
<p><strong>Routes</strong></p>
<p>To process the flow of our application we need to modify app/routes.rb to include our new pages. Here&#8217;s a snippet from the beginning of the file:</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">resources <span style="color:#ff3333; font-weight:bold;">:inventory_items</span>
&nbsp;
resources <span style="color:#ff3333; font-weight:bold;">:shipments</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  member <span style="color:#9966CC; font-weight:bold;">do</span>
    get <span style="color:#996600;">'additems'</span> <span style="color:#008000; font-style:italic;"># /shipments/1/additems</span>
    get <span style="color:#996600;">'addAll'</span>   <span style="color:#008000; font-style:italic;"># /shipments/1/addAll</span>
    get <span style="color:#996600;">'items'</span>    <span style="color:#008000; font-style:italic;"># /shipments/1/items</span>
    get <span style="color:#996600;">'remove'</span>   <span style="color:#008000; font-style:italic;"># /shipments/1/remove</span>
    get <span style="color:#996600;">'reserve'</span>  <span style="color:#008000; font-style:italic;"># /shipments/1/reserve</span>
    get <span style="color:#996600;">'manifest'</span> <span style="color:#008000; font-style:italic;"># /shipments/1/manifest</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>  
&nbsp;
get <span style="color:#996600;">&quot;home/index&quot;</span></pre></td></tr></table></div>

</p>
<p><strong>ShipmentController</strong></p>
<p>Last but not least is the ShipmentController. Controllers provide the “glue” between models and views. In Rails, controllers are responsible for processing the incoming requests from the web browser, interrogating the models for data, and passing that data on to the views for presentation. Take a look at the following code which should explain quite a bit. Since the controller contains code both generated by Rails and added by me, I&#8217;ve annotated it for your viewing ease.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> ShipmentsController <span style="color:#006600; font-weight:bold;">&lt;</span> ApplicationController
  <span style="color:#008000; font-style:italic;"># GET /shipments</span>
  <span style="color:#008000; font-style:italic;"># GET /shipments.xml</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> index
    <span style="color:#0066ff; font-weight:bold;">@shipments</span> = Shipment.<span style="color:#9900CC;">all</span>
&nbsp;
    respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#008000; font-style:italic;"># index.html.erb</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:xml</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@shipments</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># GET /shipments/1</span>
  <span style="color:#008000; font-style:italic;"># GET /shipments/1.xml</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> show
    <span style="color:#0066ff; font-weight:bold;">@shipment</span> = Shipment.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#008000; font-style:italic;"># show.html.erb</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:xml</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@shipment</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># GET /shipments/new</span>
  <span style="color:#008000; font-style:italic;"># GET /shipments/new.xml</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> new
    <span style="color:#0066ff; font-weight:bold;">@shipment</span> = Shipment.<span style="color:#9900CC;">new</span>
&nbsp;
    respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#008000; font-style:italic;"># new.html.erb</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:xml</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@shipment</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># GET /shipments/1/edit</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> edit
    <span style="color:#0066ff; font-weight:bold;">@shipment</span> = Shipment.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># CUSTOM</span>
  <span style="color:#008000; font-style:italic;"># GET /shipments/1/additems</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> additems
    <span style="color:#0066ff; font-weight:bold;">@shipment</span> = Shipment.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># get a a count of the available inventory by category</span>
    <span style="color:#0066ff; font-weight:bold;">@gloves</span> = InventoryItem.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:category</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Gloves'</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Available'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">count</span>
    <span style="color:#0066ff; font-weight:bold;">@nebulizer</span> = InventoryItem.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:category</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Nebulizer'</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Available'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">count</span>
    <span style="color:#0066ff; font-weight:bold;">@hyperinflation</span> = InventoryItem.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:category</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Hyperinflation'</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Available'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">count</span>
    <span style="color:#0066ff; font-weight:bold;">@circuit</span> = InventoryItem.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:category</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Circuits'</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Available'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">count</span>
    <span style="color:#0066ff; font-weight:bold;">@armboard</span> = InventoryItem.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:category</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Armboards'</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Available'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">count</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># CUSTOM</span>
  <span style="color:#008000; font-style:italic;"># GET /shipments/1/addAll</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> addAll
    <span style="color:#0066ff; font-weight:bold;">@shipment</span> = Shipment.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># add all of the avaiilable items for the category to the shipment as 'selected'</span>
    InventoryItem.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:category</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:category</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Available'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>item<span style="color:#006600; font-weight:bold;">|</span> 
      <span style="color:#008000; font-style:italic;"># assign the item to the shipment</span>
      item.<span style="color:#9900CC;">shipment</span> = <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">id</span>
      <span style="color:#008000; font-style:italic;"># set the status as 'selected'</span>
      item.<span style="color:#9900CC;">status</span> = <span style="color:#996600;">'Selected'</span>
      item.<span style="color:#9900CC;">save</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#008000; font-style:italic;"># update the shipment with total number of items on it</span>
    <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">items</span> = InventoryItem.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:shipment</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">count</span>
    <span style="color:#008000; font-style:italic;"># update the shipment with the total number of 'selected' items</span>
    <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">selected</span> = InventoryItem.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:shipment</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">id</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Selected'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">count</span>
    <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">save</span>
    respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> redirect_to<span style="color:#006600; font-weight:bold;">&#40;</span>@shipment, <span style="color:#ff3333; font-weight:bold;">:notice</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Items have been successfully added.'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> head <span style="color:#ff3333; font-weight:bold;">:ok</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># CUSTOM</span>
  <span style="color:#008000; font-style:italic;"># GET /shipments/1/items</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> items
    <span style="color:#0066ff; font-weight:bold;">@shipment</span> = Shipment.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># fetch all of the items on the shipment regardless of status</span>
    <span style="color:#0066ff; font-weight:bold;">@items</span> = InventoryItem.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:shipment</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">order</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># CUSTOM</span>
  <span style="color:#008000; font-style:italic;"># GET /shipments/1/manifest</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> manifest
    <span style="color:#0066ff; font-weight:bold;">@shipment</span> = Shipment.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># fetch all of the items on the shipment regardless of status</span>
    <span style="color:#0066ff; font-weight:bold;">@items</span> = InventoryItem.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:shipment</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">order</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>    
&nbsp;
  <span style="color:#008000; font-style:italic;"># CUSTOM</span>
  <span style="color:#008000; font-style:italic;"># GET /shipments/1/remove</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> remove
    <span style="color:#0066ff; font-weight:bold;">@shipment</span> = Shipment.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># remove all items on the shipment</span>
    InventoryItem.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:shipment</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>item<span style="color:#006600; font-weight:bold;">|</span> 
      <span style="color:#008000; font-style:italic;"># remove it from the shipment</span>
      item.<span style="color:#9900CC;">shipment</span> = <span style="color:#0000FF; font-weight:bold;">nil</span>
      <span style="color:#008000; font-style:italic;"># mark the item as available</span>
      item.<span style="color:#9900CC;">status</span> = <span style="color:#996600;">'Available'</span>
      item.<span style="color:#9900CC;">save</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># update the shipment with the correct counts</span>
    <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">items</span> = <span style="color:#006666;">0</span>
    <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">reserved</span> = <span style="color:#006666;">0</span>
    <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">selected</span> = <span style="color:#006666;">0</span>
    <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">save</span>
    respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> redirect_to<span style="color:#006600; font-weight:bold;">&#40;</span>@shipment, <span style="color:#ff3333; font-weight:bold;">:notice</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'All items removed from the shipment.'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> head <span style="color:#ff3333; font-weight:bold;">:ok</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># CUSTOM</span>
  <span style="color:#008000; font-style:italic;"># GET /shipments/1/reserve</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> reserve
    <span style="color:#0066ff; font-weight:bold;">@shipment</span> = Shipment.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># mark all items on the shipment as reserved</span>
    InventoryItem.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:shipment</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>item<span style="color:#006600; font-weight:bold;">|</span> 
      item.<span style="color:#9900CC;">status</span> = <span style="color:#996600;">'Reserved'</span>
      item.<span style="color:#9900CC;">save</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># get a count of the number of reserved items on the shipment</span>
    <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">reserved</span> = InventoryItem.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:shipment</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">count</span>
    <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">save</span>
    respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> redirect_to<span style="color:#006600; font-weight:bold;">&#40;</span>@shipment, <span style="color:#ff3333; font-weight:bold;">:notice</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'All items were successfully marked as reserved.'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> head <span style="color:#ff3333; font-weight:bold;">:ok</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># POST /shipments</span>
  <span style="color:#008000; font-style:italic;"># POST /shipments.xml</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> create
    <span style="color:#0066ff; font-weight:bold;">@shipment</span> = Shipment.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:shipment</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
      <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">save</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> redirect_to<span style="color:#006600; font-weight:bold;">&#40;</span>@shipment, <span style="color:#ff3333; font-weight:bold;">:notice</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Shipment was successfully created.'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:xml</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@shipment</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:created</span>, <span style="color:#ff3333; font-weight:bold;">:location</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@shipment</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#9966CC; font-weight:bold;">else</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;new&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:xml</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">errors</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:unprocessable_entity</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># PUT /shipments/1</span>
  <span style="color:#008000; font-style:italic;"># PUT /shipments/1.xml</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> update
    <span style="color:#0066ff; font-weight:bold;">@shipment</span> = Shipment.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
      <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">update_attributes</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:shipment</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> redirect_to<span style="color:#006600; font-weight:bold;">&#40;</span>@shipment, <span style="color:#ff3333; font-weight:bold;">:notice</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Shipment was successfully updated.'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> head <span style="color:#ff3333; font-weight:bold;">:ok</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#9966CC; font-weight:bold;">else</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;edit&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:xml</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">errors</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:unprocessable_entity</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># DELETE /shipments/1</span>
  <span style="color:#008000; font-style:italic;"># DELETE /shipments/1.xml</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> destroy
    <span style="color:#0066ff; font-weight:bold;">@shipment</span> = Shipment.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@shipment</span>.<span style="color:#9900CC;">destroy</span>
&nbsp;
    respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> redirect_to<span style="color:#006600; font-weight:bold;">&#40;</span>shipments_url<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> head <span style="color:#ff3333; font-weight:bold;">:ok</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

</p>
<p><strong>Summary</strong></p>
<p>That&#8217;s our application in a nutshell. <a href="http://www.jeffdouglas.com/download/ruby-part3-code.zip">You can download a zip of the entire project from here</a>. In the next part of the series we&#8217;ll dive into the <a href="http://wiki.developerforce.com/index.php/Getting_Started_with_the_Force.com_Toolkit_for_Ruby" target="_blank">Force.com Toolkit for Ruby</a> and really start to integrate with the platform.</p>
<p><strong>Related Posts:</strong></p>
<p>
<ul>
<li><a href="http://blog.jeffdouglas.com/2010/12/30/learning-ruby-for-force-com-developers-part-1/">Learning Ruby for Force.com Developers – Part 1</a>
<li><a href="http://blog.jeffdouglas.com/2011/01/11/learning-ruby-for-force-com-developers-%E2%80%93-part-2/">Learning Ruby for Force.com Developers – Part 2</a></ul></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2011/02/03/learning-ruby-for-force-com-developers-%e2%80%93-part-3/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Passing Values to JavaScript from Apex Controller Method</title>
		<link>http://blog.jeffdouglas.com/2011/01/17/passing-values-to-javascript-from-apex-controller-method/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=passing-values-to-javascript-from-apex-controller-method</link>
		<comments>http://blog.jeffdouglas.com/2011/01/17/passing-values-to-javascript-from-apex-controller-method/#comments</comments>
		<pubDate>Tue, 18 Jan 2011 03:28:50 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Code Sample]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=3533</guid>
		<description><![CDATA[I&#8217;m working on a port of an existing Java app to Salesforce.com and I ran into a Visualforce page that gave me some problems. The current JSP page allows the user to fill out a form, submit a new record to the database and then pop-up a new window to show some results while keeping [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F01%2F17%2Fpassing-values-to-javascript-from-apex-controller-method%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F01%2F17%2Fpassing-values-to-javascript-from-apex-controller-method%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;m working on a port of an existing Java app to Salesforce.com and I ran into a Visualforce page that gave me some problems. The current JSP page allows the user to fill out a form, submit a new record to the database and then pop-up a new window to show some results while keeping the users on the same page with the form.</p>
<p>This is actually somewhat difficult to do with Apex and Visualforce. I searched the message boards but couldn&#8217;t find anything comparable. Luckily <a href="http://th3silverlining.com">Wes Nolte</a> came to the rescue with his mad JavaScript skillz to point me in the right direction.</p>
<p>Typically you save a record with a commandButton that invokes a method in the Controller specified by the action attribute. However, this method returns a PageReference which, if not null, will redirect the user to a new page. However, I wanted the Controller method to notify the Visualforce page that the insert was successful and then pop open a new window via JavaScript that loaded another page.</p>
<p>Here&#8217;s something similar to what I came up with.<strong> <a href="http://jeffdouglas-developer-edition.na5.force.com/examples/ActionFunctionDemo">You can run this example on my developer site.</a></strong></p>
<p><img style="display: block; margin-left: auto; margin-right: auto;" title="action-function-demo.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2011/01/action-function-demo.png" border="0" alt="action-function-demo.png" width="550" height="262" /></p>
<p><strong>ActionFunctionDemoController</strong></p>
<p>The Controller exposes a public &#8216;message&#8217; attribute that is used by the Visualforce page to display the results of the submission. The <strong>save()</strong> method inserts the record and set the value of the &#8216;message&#8217; attribute if no error. If an error occurred, it set the error message to the &#8216;message&#8217; attribute instead.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">public with sharing class ActionFunctionDemoController {
&nbsp;
  public Cat3__c cat {get;set;}
  public String message {get;set;}
&nbsp;
  public ActionFunctionDemoController() {
    cat = new Cat3__c(name='Some Value',Cat2__c='a0B70000002PuK2EAK');
    message = 'Try again!!'; // initial message.
  }
&nbsp;
  public PageReference save() { 
    try {
      insert cat;
      message = 'Insert successful! -- ' + cat.id;
    } catch (Exception e) {
      ApexPages.addMessages(e);
      message = 'Whoops! An error occurred -- ' + e.getMessage();      
    }
    return null;
  }
&nbsp;
}</pre></td></tr></table></div>

</p>
<p><strong>ActionFunctionDemo</strong></p>
<p>The Visualforce page has a number of interesting aspects. First it defines an actionFunction which allows us to invoke a controller action method from JavaScript. The component&#8217;s name is <strong>doControllerSave</strong> and it calls the <strong>save()</strong> method in the Controller. Instead of using the action attribute, the commandButton component instead uses the onclick method to call the <strong>doControllerSave</strong> JavaScript method (which in turn calls <strong>save()</strong> action method in the Controller) and then specifies that the <strong>onControllerReturn</strong> JavaScript method should be called when the Ajax request completes on the client. The magic here is that we wrap the entire <strong>onControllerReturn</strong> function in an outputPanel which is rerendered by the ActionFunction. Without the outputPanel this entire operation doesn&#8217;t work at all.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
</pre></td><td class="code"><pre class="java" style="font-family:monospace;">&lt;apex:page controller=&quot;ActionFunctionDemoController&quot;&gt;
 &lt;apex:sectionHeader title=&quot;Action Function Demo&quot; 
  subtitle=&quot;Save a New Record&quot;/&gt;
&nbsp;
  &lt;apex:form &gt;
&nbsp;
  &lt;apex:outputPanel id=&quot;jspanel&quot;&gt; 
  &lt;script&gt;  
  function onControllerReturn() {
    alert('{!message}')
  }
  &lt;/script&gt;
  &lt;/apex:outputPanel&gt;
&nbsp;
  &lt;apex:actionFunction name=&quot;doControllerSave&quot; action=&quot;{!save}&quot; 
    rerender=&quot;jspanel&quot;/&gt;
&nbsp;
  &lt;apex:pageBlock id=&quot;blockSection&quot;&gt;
&nbsp;
  &lt;apex:pageBlockButtons &gt;
    &lt;apex:commandButton onclick=&quot;doControllerSave();&quot; 
      oncomplete=&quot;onControllerReturn()&quot; value=&quot;Save&quot;/&gt;
  &lt;/apex:pageBlockButtons&gt;
  &lt;apex:pageMessages /&gt;
&nbsp;
  &lt;apex:pageBlockSection columns=&quot;1&quot;&gt;
    &lt;apex:inputField value=&quot;{!cat.name}&quot;/&gt;  
    &lt;apex:inputField value=&quot;{!cat.Cat2__c}&quot;/&gt;  
  &lt;/apex:pageBlockSection&gt;
&nbsp;
  &lt;/apex:pageBlock&gt;
  &lt;/apex:form&gt;
&nbsp;
  Submit the form to successfully create a record. To generate an error, 
  remove the value for 'Cat2' and save.
&nbsp;
&lt;/apex:page&gt;</pre></td></tr></table></div>
</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2011/01/17/passing-values-to-javascript-from-apex-controller-method/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Learning Ruby for Force.com Developers – Part 2</title>
		<link>http://blog.jeffdouglas.com/2011/01/11/learning-ruby-for-force-com-developers-%e2%80%93-part-2/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=learning-ruby-for-force-com-developers-%25e2%2580%2593-part-2</link>
		<comments>http://blog.jeffdouglas.com/2011/01/11/learning-ruby-for-force-com-developers-%e2%80%93-part-2/#comments</comments>
		<pubDate>Tue, 11 Jan 2011 18:26:13 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Code Sample]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=3505</guid>
		<description><![CDATA[This is part #2 from my adventures of learning Ruby. If you missed part #1 you might want to take a look at it just to get up to speed. Again, these are my goals for this series: Learn Ruby Develop an app locally using Ruby on Rails and the default SQLite database Modify the [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F01%2F11%2Flearning-ruby-for-force-com-developers-%25e2%2580%2593-part-2%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.jeffdouglas.com%2F2011%2F01%2F11%2Flearning-ruby-for-force-com-developers-%25e2%2580%2593-part-2%2F&amp;source=jeffdonthemic&amp;style=normal&amp;service=bit.ly&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>This is part #2 from my adventures of learning Ruby. <a href="http://blog.jeffdouglas.com/2010/12/30/learning-ruby-for-force-com-developers-part-1/">If you missed part #1 you might want to take a look at it just to get up to speed.</a> Again, these are my goals for this series:</p>
<ul>
<li>Learn Ruby</li>
<li>Develop an app locally using Ruby on Rails and the default SQLite database</li>
<li>Modify the app to use Database.com and the Force.com Toolkit for Ruby</li>
<li>Deploy the app to <a href="http://heroku.com/">Heroku</a></li>
<li>Modify the app to use Database.com and the REST API</li>
</ul>
<p>I&#8217;ve spent the last week or so digging into the Ruby language and have found <a href="http://www.techotopia.com/index.php/Ruby_Essentials">Ruby Essentials</a>, <a href="http://www.linuxtopia.org/online_books/programming_books/ruby_tutorial/index.html">Ruby Programming</a> and <a href="http://www.tutorialspoint.com/ruby/">Ruby Tutorial</a> to be especially useful. I&#8217;m not an expert, but I do have a feel for it. I&#8217;m not going to write a Ruby tutorial (see the links above for that) but I will try to incorporate as much as possible to demonstrate things that I found useful, different or cool.</p>
<p><strong>Write an App in Ruby</strong></p>
<p>The best way to really learn a language is to actually write an app. So that&#8217;s what I&#8217;m going to do. I expect that my approach and/or assumptions may need to be tweaked once I get further down the road but we&#8217;ll see. I&#8217;m going to rewrite <a href="http://blog.jeffdouglas.com/2010/12/16/video-my-vmforce-demo-from-dreamforce/">my Dreamforce 2010 VMforce app</a> in Ruby and Rails. In a nutshell this is a shopping cart app with a little twist. I do a lot of work for <a href="http://www.medisend.org">Medisend International</a>, which is a non-profit that ships medical supplies to developing countries (among other things). They have an (old) international aid self-service portal that allows aid recipients (typically hospital administrators or local NGOs) to create a shipment and select medical supplies to be shipped to their country. If all goes well I may build the app out and put it into production on Heroku.</p>
<p>So let&#8217;s get started by looking at the domain objects for the app. We&#8217;ll need a Shipment object (of course) to manage our multiple shipments and an InventoryItem object which will represent the medical items that will be added to the shipment. These are modeled as Custom Object in my development org.</p>
<p>Before we start building out the objects, let&#8217;s step back and take a look at how Ruby works with objects. Apex isn&#8217;t exactly Java but it&#8217;s somewhat similar and a lot of Force.com developers come from a Java background. So it might help to compare Ruby and Java.</p>
<p>As with Java, you&#8217;ll find the following <strong>similar</strong> to Ruby:</p>
<ul>
<li>Memory is managed for you via a garbage collector.</li>
<li>Objects are strongly typed.</li>
<li>There are public, private, and protected methods.</li>
<li>There are embedded doc tools (Ruby’s is called RDoc). The docs generated by rdoc look very similar to those generated by javadoc.</li>
</ul>
<p>Unlike Java, you&#8217;ll find the following <strong>different</strong> in Ruby:</p>
<ul>
<li>You don’t need to compile your code. You just run it directly.</li>
<li>There are different GUI toolkits. Ruby users can try WxRuby, FXRuby, Ruby-GNOME2, or the bundled-in Ruby Tk for example.</li>
<li>You use the end keyword after defining things like classes, instead of having to put braces around blocks of code.</li>
<li>You have require instead of import.</li>
<li>All member variables are private. From the outside, you access everything via methods.</li>
<li>Parentheses in method calls are usually optional and often omitted.</li>
<li>Everything is an object, including numbers like 2 and 3.14159.</li>
<li>There’s no static type checking.</li>
<li>Variable names are just labels. They don’t have a type associated with them.</li>
<li>There are no type declarations. You just assign to new variable names as-needed and they just “spring up” (i.e. a = [1,2,3] rather than int[] a = {1,2,3};).</li>
<li>There’s no casting. Just call the methods. Your unit tests should tell you before you even run the code if you’re going to see an exception.</li>
<li>It’s foo = Foo.new( &#8220;hi&#8221;) instead of Foo foo = new Foo( &#8220;hi&#8221; ).</li>
<li>The constructor is always named “initialize” instead of the name of the class.</li>
<li>You have “mixin’s” instead of interfaces.</li>
<li>YAML tends to be favored over XML.</li>
<li>It’s nil instead of null.</li>
<li>== and equals() are handled differently in Ruby. Use == when you want to test equivalence in Ruby (equals() is Java). Use equal?() when you want to know if two objects are the same (== in Java).</li>
</ul>
<p><strong>Shipment Class</strong></p>
<p>The basic Shipment class looks like the following. It has two instance variables (name and country) and a getter and setter for each one.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Shipment
  <span style="color:#9966CC; font-weight:bold;">def</span> name
    <span style="color:#0066ff; font-weight:bold;">@name</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> name=<span style="color:#006600; font-weight:bold;">&#40;</span>value<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@name</span> = value
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> country
    <span style="color:#0066ff; font-weight:bold;">@country</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> country=<span style="color:#006600; font-weight:bold;">&#40;</span>value<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@country</span> = value
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Hello Shipment!!'</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

</p>
<p>The following script creates a new instance of the Shipment class, populates the instance variables and display them.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'./Shipment'</span> <span style="color:#008000; font-style:italic;"># similar to Java import</span>
s = Shipment.<span style="color:#9900CC;">new</span> <span style="color:#008000; font-style:italic;"># create a new instance</span>
s.<span style="color:#9900CC;">name</span> = <span style="color:#996600;">'ANG0903-COH1'</span>
s.<span style="color:#9900CC;">country</span> = <span style="color:#996600;">'Angola'</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> s.<span style="color:#9900CC;">name</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> s.<span style="color:#9900CC;">country</span></pre></td></tr></table></div>

</p>
<p>Create a new directory called &#8216;RubyDemo&#8217; (or whatever you&#8217;d like), switch to that new directory and create a file called <strong>Shipment.rb</strong>. Paste the contents of the Shipment class above into it. Create another file in that new directory called t<strong>estshipment.rb</strong> and paste the test code above into it. Now open Terminal and switch to this new directory and run <strong>ruby testshipment.rb</strong>. You should see the following:</p>
<p><img style="display: block; margin-left: auto; margin-right: auto;" title="ruby-pt2-1.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2011/01/ruby-pt2-1.png" border="0" alt="ruby-pt2-1.png" width="515" height="126" /></p>
<p>So now that we have our Shipment object we need to create our InventoryItem objects to add it. Here&#8217;s the class for our InventoryItem:</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># base class for all items</span>
<span style="color:#9966CC; font-weight:bold;">class</span> InventoryItem
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:name</span>, <span style="color:#ff3333; font-weight:bold;">:itemNumber</span>, <span style="color:#ff3333; font-weight:bold;">:category</span>, <span style="color:#ff3333; font-weight:bold;">:status</span>, <span style="color:#ff3333; font-weight:bold;">:type</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>name, itemNumber, category, type<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@name</span>, <span style="color:#0066ff; font-weight:bold;">@itemNumber</span>, <span style="color:#0066ff; font-weight:bold;">@category</span>, <span style="color:#0066ff; font-weight:bold;">@type</span> = name, itemNumber, category, type
    <span style="color:#0066ff; font-weight:bold;">@status</span> = <span style="color:#996600;">'Available'</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># override the 'to string' method</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> to_s
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Item: '</span> <span style="color:#006600; font-weight:bold;">+</span> itemNumber <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">', Name: '</span> <span style="color:#006600; font-weight:bold;">+</span> name <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">', Category: '</span> <span style="color:#006600; font-weight:bold;">+</span> category
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

</p>
<p>You&#8217;ll notice that this class is a little different than the Shipment class. Instead of manually creating getter and setter methods, I used &#8220;attr_accessor&#8221; followed by the names of all of the instance variables for my class. With this command, Ruby will generate  basic getters and setters automatically for me. I could have used &#8220;attr_reader&#8221; to generate only the getter methods and &#8220;attr_writer&#8221; to generate the setters.</p>
<p>The initialize method is a standard Ruby class method and is the method which gets called first after an object based on this class has completed initialization. Four arguments are passed into this method and they are used to set instance variable for the object. You&#8217;ll also notice that @status is set to &#8216;Available&#8217; by default each time a new object is created. The to_s method overrides the standard to_s (&#8220;to string&#8221;) method and displays some information about the item.</p>
<p><strong>Ruby Inheritance</strong></p>
<p>Unfortunately Medisend doesn&#8217;t ship just &#8220;inventory items&#8221;; they ship supplies, equipment and biomedical items. Each one of these types of items is similar but also slightly different. All items have a name, unique item number, category and status however supplies also have expiration dates and quantities of items in the box while equipment has a weight attribute. So instead of making classes for each type of InventoryItem with the same attributes we can use InventoryItem as a base class for each type of item and inherit the shared attributes and functionality from the this base class. (BTW&#8230; in salesforce.com there is a Custom Object called InventoryItem__c and Supply, Equipment and Biomed are the types of recordtypes.)</p>
<p>So here&#8217;s the SupplyItem that extends the InventoryItem class. The initialize method has 4 arguments; three of which are used to construct the InventoryItem class via the super() call and one that sets the instance variable @quantity. The method also sets a default expiration date just for fun.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'date'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'./InventoryItem'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> SupplyItem <span style="color:#006600; font-weight:bold;">&lt;</span> InventoryItem
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:quantity</span>, <span style="color:#ff3333; font-weight:bold;">:condition</span>, <span style="color:#ff3333; font-weight:bold;">:expirationDate</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>name, itemNumber, category, quantity<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">super</span><span style="color:#006600; font-weight:bold;">&#40;</span>name, itemNumber, category, <span style="color:#996600;">'Supply'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@quantity</span> = quantity
    <span style="color:#0066ff; font-weight:bold;">@expirationDate</span> = <span style="color:#CC00FF; font-weight:bold;">Date</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2012</span>, 01, 01<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

</p>
<p>The EquipmentItem class also extends InventoryItem but has it&#8217;s own to_s method allowing for a more detailed representation of item.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'./InventoryItem'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> EquipmentItem <span style="color:#006600; font-weight:bold;">&lt;</span> InventoryItem
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:weight</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>name, itemNumber, category, weight<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">super</span><span style="color:#006600; font-weight:bold;">&#40;</span>name, itemNumber, category, <span style="color:#996600;">'Equipment'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@weight</span> = weight
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># provide a custom 'to string' method for equipment only</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> to_s
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Item: '</span> <span style="color:#006600; font-weight:bold;">+</span> itemNumber <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">', Name: '</span> <span style="color:#006600; font-weight:bold;">+</span> name <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">', Category: '</span> <span style="color:#006600; font-weight:bold;">+</span> category <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">', Weight: '</span> <span style="color:#006600; font-weight:bold;">+</span> weight.<span style="color:#9900CC;">to_s</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">' lbs'</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

</p>
<p>The BiomedItem class is very similar to the SupplyItem class but adds its own weight and condition instance variables.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'./InventoryItem'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> BiomedItem <span style="color:#006600; font-weight:bold;">&lt;</span> InventoryItem
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:weight</span>, <span style="color:#ff3333; font-weight:bold;">:condition</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>name, itemNumber, category, weight<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">super</span><span style="color:#006600; font-weight:bold;">&#40;</span>name, itemNumber, category, <span style="color:#996600;">'Biomed'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@weight</span> = weight
    <span style="color:#0066ff; font-weight:bold;">@condition</span> = <span style="color:#996600;">'Unknown'</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

</p>
<p><strong>Shipment Functionality</strong></p>
<p>With all of the inventory items complete we need to turn our attention back to the Shipment class. The Shipment class should maintain a collection of InventoryItems that are assigned to it and also provide public methods to add and remove items. It should also give some kind of display of the shipment contents. Take a look at the code below along with the comments.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Shipment
  <span style="color:#008000; font-style:italic;"># class (static) variable </span>
  @@totalShipmentItems = <span style="color:#006666;">0</span>
  <span style="color:#008000; font-style:italic;"># constant</span>
  MAX_ITEMS = <span style="color:#006666;">10</span>
  <span style="color:#008000; font-style:italic;"># provides getters and setters for instance variables</span>
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:name</span>, <span style="color:#ff3333; font-weight:bold;">:country</span>, <span style="color:#ff3333; font-weight:bold;">:type</span>, <span style="color:#ff3333; font-weight:bold;">:status</span>, <span style="color:#ff3333; font-weight:bold;">:items</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># init the object &amp; set instance variables</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>name, country, type<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@name</span>, <span style="color:#0066ff; font-weight:bold;">@country</span>, <span style="color:#0066ff; font-weight:bold;">@type</span> = name, country, type
    <span style="color:#0066ff; font-weight:bold;">@status</span> = <span style="color:#996600;">'Not Shipped'</span>
    <span style="color:#0066ff; font-weight:bold;">@items</span> = <span style="color:#CC00FF; font-weight:bold;">Hash</span>.<span style="color:#9900CC;">new</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># adds an item to the Hash of shipment items</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> addItem<span style="color:#006600; font-weight:bold;">&#40;</span>item<span style="color:#006600; font-weight:bold;">&#41;</span>
    items<span style="color:#006600; font-weight:bold;">&#91;</span>item.<span style="color:#9900CC;">itemNumber</span><span style="color:#006600; font-weight:bold;">&#93;</span> = item <span style="color:#008000; font-style:italic;"># item number is the key</span>
    @@totalShipmentItems <span style="color:#006600; font-weight:bold;">+</span>= <span style="color:#006666;">1</span> <span style="color:#008000; font-style:italic;"># increment total items</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># deletes an item from the Hash of shipment items</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> deleteItem<span style="color:#006600; font-weight:bold;">&#40;</span>itemNumber<span style="color:#006600; font-weight:bold;">&#41;</span>
    items.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span>itemNumber<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;"># deleted by key</span>
    @@totalShipmentItems <span style="color:#006600; font-weight:bold;">-</span>= <span style="color:#006666;">1</span> <span style="color:#008000; font-style:italic;"># decrements total items</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># displays item number and name of each item in shipment</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> displayItems<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'These are the items in the shipment:'</span>
    items.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>key, value<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot; #{key} -- #{value.name}&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># displays item number of each item in shipment</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> displayItemNumbers<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'These are the item numbers in the shipment:'</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> items.<span style="color:#9900CC;">keys</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># displays number of items for this plus all shipments</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> numberOfItems<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Number of items in the shipment: '</span> <span style="color:#006600; font-weight:bold;">+</span> items.<span style="color:#9900CC;">length</span>.<span style="color:#9900CC;">to_s</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Total items for all shipments: '</span> <span style="color:#006600; font-weight:bold;">+</span> @@totalShipmentItems.<span style="color:#9900CC;">to_s</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Max items: '</span> <span style="color:#006600; font-weight:bold;">+</span> MAX_ITEMS.<span style="color:#9900CC;">to_s</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

</p>
<p>Now for the fun part. Let&#8217;s write a script that utilizes all of our new classes. The following script will do the following:</p>
<ol>
<li>Prompt the user to type in the name of a new shipment</li>
<li>Create and display a new supply item </li>
<li>Create and display a new equipment item</li>
<li>Create and display a new biomed item</li>
<li>Create a new shipment with the name that the user entered</li>
<li>Add the supply, equipment and biomed items to the shipment</li>
<li>Display the shipment&#8217;s instance members as well as information about the items</li>
<li>Remove the equipment item</li>
<li>Display the information about the items</li>
</ol>
<p>Save the following code in a new file called <strong>test.rb</strong>.</p>
<p>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'./Shipment'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'./SupplyItem'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'./EquipmentItem'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'./BiomedItem'</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Enter a new shipment name: &quot;</span>  
STDOUT.<span style="color:#9900CC;">flush</span>  
shipmentName = <span style="color:#CC0066; font-weight:bold;">gets</span>.<span style="color:#CC0066; font-weight:bold;">chomp</span>  
&nbsp;
s = SupplyItem.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Surgical Gloves - Size 7'</span>, <span style="color:#996600;">'LP10001'</span>, <span style="color:#996600;">'Gloves'</span>, <span style="color:#006666;">500</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'=== Sample Supply Item =='</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Name: '</span> <span style="color:#006600; font-weight:bold;">+</span> s.<span style="color:#9900CC;">name</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Item #: '</span> <span style="color:#006600; font-weight:bold;">+</span> s.<span style="color:#9900CC;">itemNumber</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Category: '</span> <span style="color:#006600; font-weight:bold;">+</span> s.<span style="color:#9900CC;">category</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Status: '</span> <span style="color:#006600; font-weight:bold;">+</span> s.<span style="color:#9900CC;">status</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Quantity: '</span> <span style="color:#006600; font-weight:bold;">+</span> s.<span style="color:#9900CC;">quantity</span>.<span style="color:#9900CC;">to_s</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Expiration Date: '</span> <span style="color:#006600; font-weight:bold;">+</span> s.<span style="color:#9900CC;">expirationDate</span>.<span style="color:#9900CC;">to_s</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> s.<span style="color:#9900CC;">to_s</span>
&nbsp;
e = EquipmentItem.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Crutches'</span>, <span style="color:#996600;">'LP50879'</span>, <span style="color:#996600;">'Mobility'</span>, <span style="color:#006666;">2.5</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'=== Sample Equipment Item =='</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Name: '</span> <span style="color:#006600; font-weight:bold;">+</span> e.<span style="color:#9900CC;">name</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Item #: '</span> <span style="color:#006600; font-weight:bold;">+</span> e.<span style="color:#9900CC;">itemNumber</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Category: '</span> <span style="color:#006600; font-weight:bold;">+</span> e.<span style="color:#9900CC;">category</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Status: '</span> <span style="color:#006600; font-weight:bold;">+</span> e.<span style="color:#9900CC;">status</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Weight: '</span> <span style="color:#006600; font-weight:bold;">+</span> e.<span style="color:#9900CC;">weight</span>.<span style="color:#9900CC;">to_s</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> e.<span style="color:#9900CC;">to_s</span>
&nbsp;
b = BiomedItem.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Clinical Laboratory - Thermostat; w/ stirrer'</span>, <span style="color:#996600;">'LP25473'</span>, <span style="color:#996600;">'Clinical Laboratory'</span>, <span style="color:#006666;">15</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'=== Sample Biomed Item =='</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Name: '</span> <span style="color:#006600; font-weight:bold;">+</span> b.<span style="color:#9900CC;">name</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Item #: '</span> <span style="color:#006600; font-weight:bold;">+</span> b.<span style="color:#9900CC;">itemNumber</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Category: '</span> <span style="color:#006600; font-weight:bold;">+</span> b.<span style="color:#9900CC;">category</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Status: '</span> <span style="color:#006600; font-weight:bold;">+</span> b.<span style="color:#9900CC;">status</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Weight: '</span> <span style="color:#006600; font-weight:bold;">+</span> b.<span style="color:#9900CC;">weight</span>.<span style="color:#9900CC;">to_s</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Condition: '</span> <span style="color:#006600; font-weight:bold;">+</span> b.<span style="color:#9900CC;">condition</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> b.<span style="color:#9900CC;">to_s</span>
&nbsp;
ship = Shipment.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>shipmentName,<span style="color:#996600;">'Albania'</span>,<span style="color:#996600;">'40ft Container'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#008000; font-style:italic;"># add items to the shipment</span>
ship.<span style="color:#9900CC;">addItem</span><span style="color:#006600; font-weight:bold;">&#40;</span>s<span style="color:#006600; font-weight:bold;">&#41;</span>
ship.<span style="color:#9900CC;">addItem</span><span style="color:#006600; font-weight:bold;">&#40;</span>e<span style="color:#006600; font-weight:bold;">&#41;</span>
ship.<span style="color:#9900CC;">addItem</span><span style="color:#006600; font-weight:bold;">&#40;</span>b<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'=== Sample Shipment =='</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Name: '</span> <span style="color:#006600; font-weight:bold;">+</span> ship.<span style="color:#9900CC;">name</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Country: '</span> <span style="color:#006600; font-weight:bold;">+</span> ship.<span style="color:#9900CC;">country</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Type: '</span> <span style="color:#006600; font-weight:bold;">+</span> ship.<span style="color:#9900CC;">type</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Status: '</span> <span style="color:#006600; font-weight:bold;">+</span> ship.<span style="color:#9900CC;">status</span>
ship.<span style="color:#9900CC;">numberOfItems</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
ship.<span style="color:#9900CC;">displayItems</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
ship.<span style="color:#9900CC;">displayItemNumbers</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'=== Deleting an Inventory Item =='</span>
ship.<span style="color:#9900CC;">deleteItem</span><span style="color:#006600; font-weight:bold;">&#40;</span>e.<span style="color:#9900CC;">itemNumber</span><span style="color:#006600; font-weight:bold;">&#41;</span>
ship.<span style="color:#9900CC;">numberOfItems</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
ship.<span style="color:#9900CC;">displayItems</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
ship.<span style="color:#9900CC;">displayItemNumbers</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></td></tr></table></div>

</p>
<p>Open Terminal again and type <strong>ruby tests.rb</strong> and you should see the following:</p>
<p><img style="display: block; margin-left: auto; margin-right: auto;" title="ruby-pt2-2.png" src="http://blog.jeffdouglas.com/wp-content/uploads/2011/01/ruby-pt2-2.png" border="0" alt="ruby-pt2-2.png" width="515" height="957" /></p>
<p>OK, so that&#8217;s a good overview of what we&#8217;ll be building. The next step is getting Rails up and running and beginning work on the web aspect. Any and all comments are welcome!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2011/01/11/learning-ruby-for-force-com-developers-%e2%80%93-part-2/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

