<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>OnRails.org: Category Playground</title>
    <link>http://onrails.org/articles/category/playground</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Ruby On Rails and related matters.</description>
    <item>
      <title>Flex Dynamic  Scaffolding for Ruby on Rails.</title>
      <description>&lt;p&gt;No I am not announcing the next killer scaffolding framework but I had a couple of hours available today so I just explored some of the cool features or Ruby On Rails and Flex. The part I was most interested in (today) is dynamic user interface creation and not generating and application like several scaffolding frameworks are doing. So I was able to create a UI that adapts to a given model of a Rails application. Of course I didn&amp;#8217;t go as far as I wished, but I thought I could share it with my readers as I usually get valuable feedback. Right now the application doesn&amp;#8217;t  even manage data. That will be the next step.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://onrails.org/files/20070804_FlexScaffolding.jpg" border="0"  width="500" alt="20070804_FlexScaffolding.jpg" align="" /&gt;
In a first phase I have adapted &lt;a href="http://railroad.rubyforge.org/"&gt;RaildRoad&lt;/a&gt; Rails model class diagram generation tool to generate an xml definition that the UI would use to create it&amp;#8217;s components. I generated an xml model for &lt;a href="http://trac.streamlinedframework.org/wiki/SampleProject"&gt;Sports&lt;/a&gt; a sample application provided with Streamlined and &lt;a href="http://typosphere.org/"&gt;Typo&lt;/a&gt; a blog server.&lt;/p&gt;


	&lt;p&gt;The UI generation from the typo model is quite cpu intensive. There is not lazy instanciation of components, when you select the model, all the Tabs, lists and forms are created.&lt;/p&gt;


	&lt;p&gt;You can &lt;a href="http://nouvelles-solutions.com/onrails/flexscaffolding/FlexScaffolding#"&gt;run the application&lt;/a&gt; and press view source from the context menu. Or you can see the source &lt;a href="http://nouvelles-solutions.com/onrails/flexscaffolding/srcview/index.html"&gt;here&lt;/a&gt;. The generated xml can be seen &lt;a href="http://nouvelles-solutions.com/onrails/flexscaffolding/srcview/source/sports_models.xml.txt"&gt;here&lt;/a&gt; and &lt;a href="http://nouvelles-solutions.com/onrails/flexscaffolding/srcview/source/typo_models.xml.txt"&gt;here&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;In a second phase I created a Flex application that generates a UI from the given xml.&lt;/p&gt;


	&lt;p&gt;I was writing this blog entry while coding, so if you are more curious about how all this works, keep on reading.&lt;/p&gt;


&lt;h1&gt;Getting the schema of your ActiveRecords&lt;/h1&gt;

	&lt;p&gt;We will generate an xml version of the schema that Flex can use to assemble a UI. So we need to find out info about each ActiveRecord of the application, it&amp;#8217;s association with other ActiveRecords, and all it&amp;#8217;s attributes. Later on would also be nice to identify the validation rules, so that we can build some validations on the fly without having to do a server round trip for some of the basic validations, (required, length, confirmation, regex). Supporting the various acts_as could also provide lots of functionality that doesn&amp;#8217;t need to be coded over and over.&lt;/p&gt;


	&lt;p&gt;I will use the Streamlined Sports example database to experiment with. Later on we may have a look at Typo a blog server.&lt;/p&gt;


	&lt;p&gt;Let&amp;#8217;s use the community to see how to parse the ActiveRecord. I am now checking out &lt;a href="http://railroad.rubyforge.org"&gt;RailRoad (0.4.0)&lt;/a&gt; a class diagram generator for Rails. Railroad has the ModelsDiagram class that gather the information we need and then uses the DiagramGraph class to generate a &lt;em&gt;dot&lt;/em&gt; format file that in turn is used to generate .svg or .png of the diagram. We are not interested in the dot generation, but will just &amp;#8216;adapt&amp;#8217; the to_dot method to get the xml we need. So I simply reopened the class and created a new &lt;i&gt;to_dot&lt;/i&gt; method as follows:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;# http://chadfowler.com/2007/8/3/enumerable-injecting&lt;/span&gt;
&lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;Enumerable&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;injecting&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;inject&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;s&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;k&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="keyword"&gt;yield&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;k&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;);&lt;/span&gt; &lt;span class="ident"&gt;k&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;DiagramGraph&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;to_dot&lt;/span&gt;
    &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="ident"&gt;definition&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_xml&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:root&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;active_records&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:dasherize&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="comment"&gt;#Let organize the data in a way closer to the xml we want to generate.&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;definition&lt;/span&gt;
    &lt;span class="ident"&gt;active_records&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{}&lt;/span&gt;
    &lt;span class="attribute"&gt;@nodes&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;node&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; 
      &lt;span class="ident"&gt;attributes&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;node&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;injecting&lt;/span&gt;&lt;span class="punct"&gt;({})&lt;/span&gt; &lt;span class="punct"&gt;{|&lt;/span&gt;&lt;span class="ident"&gt;accumulator&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;value&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;k&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="ident"&gt;v&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="ident"&gt;value&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;split&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt; :&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;);&lt;/span&gt; &lt;span class="ident"&gt;accumulator&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;k&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;v&lt;/span&gt;&lt;span class="punct"&gt;}&lt;/span&gt;
      &lt;span class="ident"&gt;class_name&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;node&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
      &lt;span class="ident"&gt;active_records&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;class_name&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="symbol"&gt;:name&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;class_name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:attributes&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;attributes&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:relations&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;[]&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="attribute"&gt;@edges&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;edge&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; 
      &lt;span class="ident"&gt;association_type&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;edge&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
      &lt;span class="ident"&gt;from_class_name&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;edge&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
      &lt;span class="ident"&gt;to_class_name&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;edge&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
      &lt;span class="ident"&gt;active_records&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;from_class_name&lt;/span&gt;&lt;span class="punct"&gt;][&lt;/span&gt;&lt;span class="symbol"&gt;:relations&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="ident"&gt;association_type&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_sym&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;to_class_name&lt;/span&gt;&lt;span class="punct"&gt;}&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="ident"&gt;active_records&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;  

&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;The &lt;em&gt;definition&lt;/em&gt; method generates a hash map with the information of the model. The &lt;em&gt;to_xml&lt;/em&gt; is all that is needed to get an &lt;a href="http://nouvelles-solutions.com/onrails/flexscaffolding/srcview/source/sports_models.xml.txt"&gt;xml version&lt;/a&gt; of the data that the map contains.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;definition&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_xml&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:root&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;active_records&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:dasherize&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;false&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h1&gt;Dynamically Generate a Flex UI&lt;/h1&gt;

	&lt;p&gt;Let looks at the model.&lt;/p&gt;


&lt;pre&gt;
Player has_many Sponsor
Coach has_many Sponsor
Team has_one Coach
           has_many Player
Sponsor has nobody!
&lt;/pre&gt;

	&lt;p&gt;The UI generation should be lot smarter and configurable. For now I have taken the approach to create one view for each model. This view shows all the records in a data grid and the detail of the selected record in a form view. All associations of the record are represented by a Tab Navigator. You will notice that this is not very practical for the Typo datamodel. We should have main ActiveRecords that are entry points to the application.  Also the depth of the active record view is one association down but could be driven by definition i.e. Team =&amp;gt; Coach =&amp;gt; Sponsor, similar to the :include option of the find methods. We should be able to flatten a &amp;#8220;to one&amp;#8221; relation and have all the attributes of the association in the same view than the source ActiveRecord.&lt;/p&gt;


	&lt;p&gt;You can &lt;a href="http://nouvelles-solutions.com/onrails/flexscaffolding/FlexScaffolding"&gt;run the application&lt;/a&gt; and &lt;a href="http://nouvelles-solutions.com/onrails/flexscaffolding/srcview/index.html"&gt;view the source&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;The main application, FlexScaffolding, adds dynamically a ActiveRecordsView for each ActiveRecord in the model to the Tab navigator. That&amp;#8217;s too many tabs for the Typo model&amp;#8230;&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;    private function generateView():void {
          for each (var activeRecord:XML in definition.children()) {
               var arView:ActiveRecordsView = new ActiveRecordsView();
               arView.definition = activeRecord;
               mainView.addChild(arView);
          }        
    }       &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;The ActiveRecordsView.mxml does the main work of generating the UI. It&amp;#8217;s not very big (66 lines), but is also limited for now. I let you check out the source code if you a curious. Next on the list is to map too more data types (ie a &amp;#8220;text&amp;#8221; ActiveRecord attribute should be mapped to a TextArea, date and datetime should be support). I need to add configuration options where the defaults can be overridden. I need to create a Rails controller that uses the same  xml model to expose the data to the view. There shouldn&amp;#8217;t be the need to hand code RESTFul controllers. Or maybe the UI should be build from the routes&amp;#8230;&lt;/p&gt;


	&lt;p&gt;That&amp;#8217;s all for now. Enjoy!
Daniel Wanja&lt;/p&gt;</description>
      <pubDate>Sun, 05 Aug 2007 04:31:57 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:883060a9-9a41-40a6-99df-75db76139344</guid>
      <author>Daniel Wanja</author>
      <link>http://onrails.org/articles/2007/08/05/flex-dynamic-scaffolding-for-ruby-on-rails</link>
      <category>Ruby On Rails</category>
      <category>Playground</category>
      <category>Flex</category>
    </item>
    <item>
      <title>RailsLogAnalyzer v0.2 for OSX - Faster, Better</title>
      <description>Version 0.2 of the RailsLogAnalyzer is still a development version but a great improvement over my first prototype. This version has been rewritten from the ground up and doesn't use a database to store intermediate log file aggreation.

&lt;img src="http://onrails.org/files/RailsLogAnalyzerActionView.gif" border="0" height="396" width="564" alt="RailsLogAnalyzerActionView.gif" align="right" /&gt;
 

&lt;p/&gt;
&lt;b&gt;Analyzing your log file data.&lt;/b&gt;

Once the log file is loaded you will see a breakdown of your requests by year, month, and day.
Click on the year, month, or day to see the controllers invocations during that period.
Click on the controller in the chart to see the method invocations during the selected period.
The method are further broken down based on their http methods (get, post, delete, ...).

Note: loading a 10Mb  production log file with 30000  requests takes about 10 seconds on my MacBook Pro.
        loading a 250Mb production log file with 530000 requests takes about 2 minutes.
        loading a 4.5Gb production log file with 11 million request takes about 45 minutes. 
The data is loaded in memory and must be reloaded once the application is closed.   

Download it here &lt;a href="http://onrails.org/files/RailsLogAnalyzer_0.2.dmg"&gt;RailsLogAnalyzer_0.2.dmg (487KB)&lt;/a&gt; and let me know your findings at daniel@onrails.org


</description>
      <pubDate>Wed, 15 Nov 2006 22:05:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:e1fdc8cd-c7e0-4916-855b-8a68a835600c</guid>
      <author>Daniel Wanja</author>
      <link>http://onrails.org/articles/2006/11/15/railsloganalyzer-v0-2-for-osx-faster-better</link>
      <category>Ruby On Rails</category>
      <category>Playground</category>
      <category>Log</category>
      <category>Analyzer</category>
    </item>
    <item>
      <title>RailsLogAnalyzer – help wanted</title>
      <description>&lt;p&gt;I need some Mac users to test and give feed back on a very early version of the RailsLogAnalyzer.  This app is an &lt;span class="caps"&gt;OSX&lt;/span&gt; app and not deployed on a server, so I would like to find out the obvious bug that may occur on different Macs. I tried it on my own MacBook Pro, G5    server, and on an old PowerBook G4. But then again the people most likely to use it are Rails developers that may have differences in their environment.&lt;/p&gt;


	&lt;p&gt;So if you like to take risks :-), understand the basic structure of a Rails app, have a production.log you want to analyze, and are not afraid of some scary bugs then read on&amp;#8230;&lt;/p&gt;&lt;p&gt;The RailsLogAnalyzer is an &lt;span class="caps"&gt;OSX&lt;/span&gt; application that allows to visualize the production.log of a Rails application. The RailsLogAnalyzer is itself a Rails application, with a Flash user interface, and wrapped as an &lt;span class="caps"&gt;OSX&lt;/span&gt; app using Platypus.&lt;/p&gt;


	&lt;p&gt;To use the application you &amp;#8216;just&amp;#8217; need to drop it in your application folder (or where ever you want) and double click it. See the &amp;#8216;user guide&amp;#8217; here after.&lt;/p&gt;


	&lt;p&gt;I wrote this small utility to help me see how users where using different Rails applications I was working on by visualizing the production log data. This utility is just doing what I needed and is pretty basic. It&amp;#8217;s definitively not ready for prime time, however your input will help drive it&amp;#8217;s development.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Requirements:&lt;/strong&gt;&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;You need the Flash Player 9. For intel macs the player is in beta and can be downloaded here http://fpdownload.macromedia.com/get/flashplayer/current/fp9_beta/install_flash_player_9_ub_beta.dmg. More info here http://www.adobe.com/products/flashplayer/public_beta/. For PowerPC macs, just starting the application will open a browser window that will guide you through the flash player upgrade if you don&amp;#8217;t have version 9 installed.&lt;/li&gt;
		&lt;li&gt;Port 3000 needs to be free. So don&amp;#8217;t run any other Rails app when you launch the application. &lt;/li&gt;
		&lt;li&gt;Don&amp;#8217;t click too fast. See the user guide here after for more information.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;&lt;strong&gt;What the application does&lt;/strong&gt;&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Show graph of unique session and total request per day.&lt;/li&gt;
		&lt;li&gt;Show pie chart of controller usage (at end of the period observed) .&lt;/li&gt;
		&lt;li&gt;Show the top ten actions invoked (can be filter by http method and controller)&lt;/li&gt;
		&lt;li&gt;Show the graphical geoip information ((at end of the period observed). [Very buggy]&lt;/li&gt;
		&lt;li&gt;Allow time navigation (30 days/7 days increment)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;&lt;strong&gt;What it doesn&amp;#8217;t do so well&lt;/strong&gt;&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Visual feedback when processing. You gotta check the launch window output to see if it&amp;#8217;s still busy.&lt;/li&gt;
		&lt;li&gt;Disable buttons when processing. You can there overload the server if you are not patient.&lt;/li&gt;
		&lt;li&gt;Report errors. In corner cases you have to open the log file that are inside the application pacakage. Use the &amp;#8216;Show Package Contents&amp;#8217; on the application then goto to /Contents/Resources/RailsLogAnalyzerPackage/log folder.&lt;/li&gt;
		&lt;li&gt;Time aggregation. It would be nice to see data aggregated by week/month.&lt;/li&gt;
		&lt;li&gt;Local File Browsing to upload the log file. Currently you need to enter the full path to the file, there is not UI to select a file.&lt;/li&gt;
		&lt;li&gt;Log parsing. Certainly can be greatly improved. Haven&amp;#8217;t tried to parse development files. Wouldn&amp;#8217;t support custom log files either. Doesn&amp;#8217;t support well multi processes logging to the same production.log (which is most cases).&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;&lt;strong&gt;Licenses&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Well, I still need to put a complete list of what I use and the implications there off. Mostly Rails which is &lt;span class="caps"&gt;MIT&lt;/span&gt; and the GeoLiteCity.dat from maxmind.com/ that is &lt;span class="caps"&gt;GPL &lt;/span&gt;. Note the GeoLiteCity.dat file is 24mb big, thus at least partly the large size of the application. Also I am using the Flex Charting Trial components, that&amp;#8217;s visible when the application is running. My trial is running out in 17days as of this writing. I would like to buy the version of Flex Builder with Charting, but Adobe hasn&amp;#8217;t answered yet if buying the license for Windows would grant me usage of the version for &lt;span class="caps"&gt;OSX&lt;/span&gt;, when it comes out.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Performances&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;The application doesn&amp;#8217;t provide the best visual feed back yet. It also takes about 1 minute on my MacBook Pro to load a 20Mb production log file and 13 minutes for a 264Mb production log.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Side notes&lt;/strong&gt;&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;The database is a sqlite3 and is created in your  /Users/daniel/Library/Application\ Support/RailsLogAnalyzer&lt;/li&gt;
		&lt;li&gt;Note the application must be &amp;#8216;read-write&amp;#8217;. Use &amp;#8216;Get Info&amp;#8217; on the application and ensure in the &amp;#8216;Ownership &amp;#38; Permissions&amp;#8217; that the application is &amp;#8216;Read &amp;#38; Write&amp;#8217;. This is due to the fact that rails needs to write to the tmp folder and log folder that are embedded in the application it self.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Please provide feedback to daniel@onrails.org. 
Thanks in advance,
Daniel.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://onrails.org/RailsLogAnalyzer0.1.dmg "&gt;Download RailsLogAnalyzer0.1.dmg (18.6MB)&lt;/a&gt;&lt;br&gt;
&lt;a href="http://onrails.org/pages/RailsLogAnalyzerUserGuide.html" target="_blank"&gt;User Guide&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 03 Aug 2006 22:37:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:19782f89-ac13-4b7c-afc0-7b3153053b90</guid>
      <author>Daniel Wanja</author>
      <link>http://onrails.org/articles/2006/08/03/railsloganalyzer-%E2%80%93-help-wanted</link>
      <category>Playground</category>
      <category>Ruby On Rails</category>
      <category>Flex</category>
      <category>Analyzer</category>
      <category>Log</category>
      <category>Rails</category>
    </item>
    <item>
      <title>Rails Log Analyzer - Rails and Flex with JSON</title>
      <description>&lt;p&gt;&lt;img src="/files/20060515_railsloganalyzer.gif" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;I started to write a small Rails Log Analyzer that provides some insight on how a given application is used. I&amp;#8217;ve just spent three hours so far, so not too much to show, but I have found the integration of Flex with Rails for read-only purpose of the different time series pretty straight forward.&lt;/p&gt;


	&lt;h2&gt;In two words&amp;#8230;&lt;/h2&gt;


	&lt;p&gt;&lt;span class="caps"&gt;RAILS&lt;/span&gt;: data.to_json&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;FLEX&lt;/span&gt;: JSON.decode(String(srv.lastResult));&lt;/p&gt;


	&lt;h2&gt;On the Rails side&lt;/h2&gt;


	&lt;p&gt;The controller simply transforms the Hash return by the model into a json textual representation.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;div class="codetitle"&gt;the controller&lt;/div&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;DataController&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ApplicationController&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;overview&lt;/span&gt;
    &lt;span class="ident"&gt;render&lt;/span&gt; &lt;span class="symbol"&gt;:text&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;Hit&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;overview_data&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_json&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;This is an extract of the method that returns a Hash that contains the time series in an Array.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;div class="codetitle"&gt;the model&lt;/div&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;Hit.overview_data&lt;/span&gt;
    &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{}&lt;/span&gt;
    &lt;span class="ident"&gt;result&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:header&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="symbol"&gt;:period&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="symbol"&gt;:start&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;Hit&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;minimum&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:time&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:db&lt;/span&gt;&lt;span class="punct"&gt;),&lt;/span&gt; &lt;span class="symbol"&gt;:end&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;Hit&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;maximum&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:time&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:db&lt;/span&gt;&lt;span class="punct"&gt;)}}&lt;/span&gt;
    &lt;span class="ident"&gt;result&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:sessions_series&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt;
           &lt;span class="punct"&gt;{&lt;/span&gt;&lt;span class="symbol"&gt;:by_day&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;Hit&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;data_serie&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;Hit&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;count&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:session&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:group&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:day&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:conditions&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;controller &amp;lt;&amp;gt; &amp;quot;HeartbeatController&amp;quot;&lt;/span&gt;&lt;span class="punct"&gt;'),&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;sessions by day&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;    &lt;span class="punct"&gt;}&lt;/span&gt;
    &lt;span class="ident"&gt;result&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;   

	&lt;h2&gt;On the Flex side&lt;/h2&gt;


&lt;div class="typocode"&gt;&lt;div class="codetitle"&gt;the view&lt;/div&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;
   import com.macromedia.serialization.json.*;

   private function resultHandler(event:ResultEvent) : void
        {
            status = &amp;quot;Loaded. Parsing data...&amp;quot;;
            var result:Object = JSON.decode(String(srv.lastResult));
            header = result.header;
            ts = getSerie(result.sessions_series.by_day.data);

  }

    &amp;lt;mx:HTTPService id=&amp;quot;srv&amp;quot; url=&amp;quot;http://10.37.129.2:3000/data/overview&amp;quot; result=&amp;quot;resultHandler(event)&amp;quot; /&amp;gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;   

	&lt;p&gt;The service is invoked by the following actionscript call&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;        &lt;span class="ident"&gt;srv&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;&lt;span class="caps"&gt;JSON&lt;/span&gt; doesn&amp;#8217;t support Date objects out of the box, but it&amp;#8217;s a nice way to exchange complex data such a Hash and Map between Rails and Flex.&lt;/p&gt;</description>
      <pubDate>Mon, 15 May 2006 21:15:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:c53bb291-118a-4b1f-a26f-fdfc6924bf89</guid>
      <author>Daniel Wanja</author>
      <link>http://onrails.org/articles/2006/05/15/rails-log-analyzer-rails-and-flex-with-json</link>
      <category>Playground</category>
      <category>JSON</category>
      <category>Flex</category>
    </item>
    <item>
      <title>.rjs and link_to_function</title>
      <description>&lt;p&gt;A neat little trick is that .rjs templates can be used to generate local javascript functions and be invoked without doing a server roundtrip.&lt;/p&gt;


&lt;strong&gt;playground_controller.rb&lt;/strong&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;PlaygroundController&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;rjs&lt;/span&gt;
     &lt;span class="ident"&gt;response&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;headers&lt;/span&gt;&lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;content-type&lt;/span&gt;&lt;span class="punct"&gt;']&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;text/html&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;strong&gt;rjs.rhtml&lt;/strong&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ident"&gt;html&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ident"&gt;head&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;%=&lt;/span&gt;&lt;span class="string"&gt; javascript_include_tag :defaults %&amp;gt;    
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;h1 id&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;header&lt;/span&gt;&lt;span class="punct"&gt;'&amp;gt;&lt;/span&gt;&lt;span class="constant"&gt;Javascript&lt;/span&gt; &lt;span class="ident"&gt;function&lt;/span&gt; &lt;span class="ident"&gt;test&lt;/span&gt;&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="regex"&gt;h1&amp;gt;

&amp;lt;%= link_to_function('Add', 'add_item()' ) -%&amp;gt; | 
&amp;lt;%= link_to_function('Clear', 'clear_list()') %&amp;gt;
    &amp;lt;ul id='list' &lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ident"&gt;script&lt;/span&gt; &lt;span class="ident"&gt;type&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;text/javascript&lt;/span&gt;&lt;span class="punct"&gt;'&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;%=&lt;/span&gt;&lt;span class="string"&gt; render :partial &lt;/span&gt;&lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;functions&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:type&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;rjs&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="string"&gt;
&amp;lt;/script&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ident"&gt;script&lt;/span&gt; &lt;span class="ident"&gt;type&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;text/javascript&lt;/span&gt;&lt;span class="punct"&gt;'&amp;gt;&lt;/span&gt;
    &lt;span class="punct"&gt;&amp;lt;%=&lt;/span&gt;&lt;span class="string"&gt; # Note: following javascript is run when the page is loaded.
        update_page do |page|
            3.times { page.call 'add_item' }
        end
    %&amp;gt;
    &amp;lt;/script&amp;gt;    
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;The &lt;em&gt;rjs&lt;/em&gt; method in the &lt;em&gt;PlaygroundController&lt;/em&gt; set&amp;#8217;s the content-type as we perform a render of an rjs from within a .rhtml and this seems to change the content-type, so we need to reset it.&lt;/p&gt;


&lt;strong&gt;_function.rjs&lt;/strong&gt;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;page&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;function add_item() {&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
    &lt;span class="ident"&gt;page&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;insert_html&lt;/span&gt; &lt;span class="symbol"&gt;:bottom&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;list&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;content_tag&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;li&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;item&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:id&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;list_item&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;page&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;visual_effect&lt;/span&gt; &lt;span class="symbol"&gt;:highlight&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;list&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:duration&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;
&lt;span class="ident"&gt;page&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;}&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="ident"&gt;page&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;function clear_list() {&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
    &lt;span class="ident"&gt;page&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;replace_html&lt;/span&gt; &lt;span class="symbol"&gt;:list&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="ident"&gt;page&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;visual_effect&lt;/span&gt; &lt;span class="symbol"&gt;:highlight&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;list&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:duration&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="number"&gt;3&lt;/span&gt;
&lt;span class="ident"&gt;page&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;}&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;In the partial _function.rjs we insert the function declaration before writing to the page object. This allows us to invoke the add_item _ and clear_list _ methods using the  link_to_function _ from in the .rhtml file. Note also in the .rhtml file we invoke directly the update_page method to insert three calls to add_item().&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;The generated html files looks like this&lt;/strong&gt;&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ident"&gt;html&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ident"&gt;head&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ident"&gt;script&lt;/span&gt; &lt;span class="ident"&gt;src&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;/javascripts/prototype.js&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="ident"&gt;type&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;text/javascript&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="regex"&gt;script&amp;gt;
&amp;lt;script src=&amp;quot;&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;javascripts&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;effects&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;js&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt; type=&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="ident"&gt;text&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;javascript&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;/&lt;/span&gt;&lt;span class="ident"&gt;javascripts&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;dragdrop&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;js&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt; type=&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="ident"&gt;text&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;javascript&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;/&lt;/span&gt;&lt;span class="ident"&gt;javascripts&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;controls&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;js&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt; type=&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="ident"&gt;text&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;javascript&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;gt;&amp;lt;/script&amp;gt;    
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;h1 id='header'&amp;gt;Javascript function test&amp;lt;/h1&amp;gt;

&amp;lt;a href=&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="comment"&gt;#&amp;quot; onclick=&amp;quot;add_item(); return false;&amp;quot;&amp;gt;Add&amp;lt;/a&amp;gt; | &lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="ident"&gt;href&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;#&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="ident"&gt;onclick&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;clear_list(); return false;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&amp;gt;&lt;/span&gt;&lt;span class="constant"&gt;Clear&lt;/span&gt;&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="regex"&gt;a&amp;gt;
    &amp;lt;ul id='list' &lt;/span&gt;&lt;span class="punct"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="ident"&gt;script&lt;/span&gt; &lt;span class="ident"&gt;type&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;text/javascript&lt;/span&gt;&lt;span class="punct"&gt;'&amp;gt;&lt;/span&gt;
  &lt;span class="ident"&gt;function&lt;/span&gt; &lt;span class="ident"&gt;add_item&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;
&lt;span class="ident"&gt;new&lt;/span&gt; &lt;span class="constant"&gt;Insertion&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;Bottom&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;list&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;lt;li id=&lt;span class="escape"&gt;\&amp;quot;&lt;/span&gt;list_item&lt;span class="escape"&gt;\&amp;quot;&lt;/span&gt;&amp;gt;item&amp;lt;/li&amp;gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;);&lt;/span&gt;
&lt;span class="ident"&gt;new&lt;/span&gt; &lt;span class="constant"&gt;Effect&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;Highlight&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;list&lt;/span&gt;&lt;span class="punct"&gt;',{&lt;/span&gt;&lt;span class="ident"&gt;duration&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;&lt;span class="number"&gt;3&lt;/span&gt;&lt;span class="punct"&gt;});&lt;/span&gt;
&lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="ident"&gt;function&lt;/span&gt; &lt;span class="ident"&gt;clear_list&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt;
&lt;span class="constant"&gt;Element&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;update&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;list&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;);&lt;/span&gt;
&lt;span class="ident"&gt;new&lt;/span&gt; &lt;span class="constant"&gt;Effect&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;Highlight&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;list&lt;/span&gt;&lt;span class="punct"&gt;',{&lt;/span&gt;&lt;span class="ident"&gt;duration&lt;/span&gt;&lt;span class="punct"&gt;:&lt;/span&gt;&lt;span class="number"&gt;3&lt;/span&gt;&lt;span class="punct"&gt;});&lt;/span&gt;
&lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="regex"&gt;script&amp;gt;
    &amp;lt;script type='text&lt;/span&gt;&lt;span class="punct"&gt;/&lt;/span&gt;&lt;span class="ident"&gt;javascript&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;&amp;gt;
    add_item();
        add_item();
        add_item();
    &amp;lt;/script&amp;gt;    
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;span class="normal"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <pubDate>Thu, 12 Jan 2006 05:57:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:212b06e3-11a1-43fb-8a2e-b3f0ea78b38d</guid>
      <author>Daniel Wanja</author>
      <link>http://onrails.org/articles/2006/01/12/rjs-and-link_to_function</link>
      <category>Playground</category>
    </item>
    <item>
      <title>Xml Builder</title>
      <description>&lt;p&gt;I created the new &lt;em&gt;Playground&lt;/em&gt; category on this blog to expose various aspects regarding Ruby On Rails that I am exploring. It may raise more questions than provide answers, but in any case don&amp;#8217;t hesitate to jump in and add your 2 cents.&lt;/p&gt;


	&lt;p&gt;The &lt;em&gt;xml_builder&lt;/em&gt; method here after uses the &lt;em&gt;render_to_string method to create some xml structure. The xml_string could as well have been in a separate .rxml file and and a simple _render&lt;/em&gt; statement instead of &lt;em&gt;render_as_string&lt;/em&gt; could have saved one line of code. But hey, that&amp;#8217;s what the playground is for!&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;PlaygroundController&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ApplicationController&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;xml_builder&lt;/span&gt;
    &lt;span class="ident"&gt;xml_string&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="constant"&gt;XML_END&lt;/span&gt;&lt;span class="string"&gt;
        xml.test do
          xml.language(name)
          xml.description(&amp;quot;Rocks!&amp;quot;)
        end
&lt;/span&gt;&lt;span class="constant"&gt;    XML_END&lt;/span&gt;
    &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;render_to_string&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:inline&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;xml_string&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:locals&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="symbol"&gt;:name&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Ruby&lt;/span&gt;&lt;span class="punct"&gt;'},&lt;/span&gt; &lt;span class="symbol"&gt;:type&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:rxml&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; 
    &lt;span class="ident"&gt;render_text&lt;/span&gt; &lt;span class="ident"&gt;result&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

The output: 
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_xml "&gt;&lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;test&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;language&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;Ruby&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;language&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt;&lt;span class="tag"&gt;description&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;Rocks!&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;description&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="punct"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="tag"&gt;test&lt;/span&gt;&lt;span class="punct"&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
      <pubDate>Tue, 10 Jan 2006 21:10:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:6960dcfd-4972-45c3-91f2-3a7e2f173e25</guid>
      <author>Daniel Wanja</author>
      <link>http://onrails.org/articles/2006/01/10/xml-builder</link>
      <category>Playground</category>
    </item>
  </channel>
</rss>
