Flex Dynamic Scaffolding for Ruby on Rails.

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’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’t even manage data. That will be the next step.

20070804_FlexScaffolding.jpg
In a first phase I have adapted RaildRoad Rails model class diagram generation tool to generate an xml definition that the UI would use to create it’s components. I generated an xml model for Sports a sample application provided with Streamlined and Typo a blog server.

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.

You can run the application and press view source from the context menu. Or you can see the source here. The generated xml can be seen here and here

In a second phase I created a Flex application that generates a UI from the given xml.

I was writing this blog entry while coding, so if you are more curious about how all this works, keep on reading.

Getting the schema of your ActiveRecords

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’s association with other ActiveRecords, and all it’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’t need to be coded over and over.

I will use the Streamlined Sports example database to experiment with. Later on we may have a look at Typo a blog server.

Let’s use the community to see how to parse the ActiveRecord. I am now checking out RailRoad (0.4.0) 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 dot 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 ‘adapt’ the to_dot method to get the xml we need. So I simply reopened the class and created a new to_dot method as follows:

# http://chadfowler.com/2007/8/3/enumerable-injecting
module Enumerable
  def injecting(s)
    inject(s) do |k, i|
      yield(k, i); k
    end
  end
end

class DiagramGraph

  def to_dot
    return definition.to_xml(:root => 'active_records', :dasherize => false)
  end
  
  #Let organize the data in a way closer to the xml we want to generate.
  def definition
    active_records = {}
    @nodes.each do |node| 
      attributes = node[2].injecting({}) {|accumulator, value| k,v=value.split(" :"); accumulator[k] = v}
      class_name = node[1]
      active_records[class_name] = { :name => class_name, :attributes => attributes, :relations => [] }
    end
    @edges.each do |edge| 
      association_type = edge[0]
      from_class_name = edge[1]
      to_class_name = edge[2]
      active_records[from_class_name][:relations] << {association_type.to_sym => to_class_name}
    end
    active_records
  end  
  
end

The definition method generates a hash map with the information of the model. The to_xml is all that is needed to get an xml version of the data that the map contains.

definition.to_xml(:root => 'active_records', :dasherize => false)

Dynamically Generate a Flex UI

Let looks at the model.

Player has_many Sponsor
Coach has_many Sponsor
Team has_one Coach
           has_many Player
Sponsor has nobody!

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 => Coach => Sponsor, similar to the :include option of the find methods. We should be able to flatten a “to one” relation and have all the attributes of the association in the same view than the source ActiveRecord.

You can run the application and view the source.

The main application, FlexScaffolding, adds dynamically a ActiveRecordsView for each ActiveRecord in the model to the Tab navigator. That’s too many tabs for the Typo model…

    private function generateView():void {
          for each (var activeRecord:XML in definition.children()) {
               var arView:ActiveRecordsView = new ActiveRecordsView();
               arView.definition = activeRecord;
               mainView.addChild(arView);
          }        
    }       

The ActiveRecordsView.mxml does the main work of generating the UI. It’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 “text” 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’t be the need to hand code RESTFul controllers. Or maybe the UI should be build from the routes…

That’s all for now. Enjoy!
Daniel Wanja

Posted by Daniel Wanja Sun, 05 Aug 2007 04:31:57 GMT


Updated: http://time.onrails.org

Time.onrails.org – a simple time tracking application has been updated.

  • Time shifting – Let’s assume you entered time from 08:00-12:00 13:00-17:00. Then you notice that you effectively took a longer lunch. Simply edit the 12:00 to 11:45, then tab to the next field and change 13:00 to 13:15 and press enter. In the same way, if you didn’t come back from lunch at all that day. Simply clear out the 13:00-17:00 field and press enter. This will delete this time slot.
  • Running Timers – When a timer is running (i.e. 11:30- ), the time line (day) is highlighted in green. That way it’s easy to detect which timers are still running.
  • IE6 Support. Time entry was pretty broken with IE. This should have been fixed. I haven’t installed IE7…so I assume it doesn’t work there.
  • Rails Migration. Behind the scenes Rails was migrated from 1.1.6 to 1.2.3.

20070713_timeonrails.jpg

Please let me know if you find anything unusual.

Enjoy!
Daniel.

Posted by Daniel Wanja Sat, 14 Jul 2007 04:46:24 GMT


RailsLogVisualizer meets Adobe AIR

I recompiled the Log Visualizer with Adobe AIR. You can download it here.

20070702RailsLogVisualizer.jpg

I tried it under Windows XP (Parallels) and it seems that the File.browseForOpen doesn’t fire the Event.SELECT event under Windows. So the bug is that you can open a file, but the application doesn’t know when you selected it. I was contacted by Logan today who wanted to know if there is a Windows version. So sorry for the Windows users out there for the moment. Note that the Apollo version of the Log Visualizer was working under windows.

Download: RailsLogVisualizer0.5.air

Posted by Daniel Wanja Tue, 03 Jul 2007 03:22:59 GMT


Open For Business: eBay Desktop Beta - an Adobe AIR Application.

The invitations are going out! So, if you haven’t yet, go signup for the eBay Desktop beta (code name Project “San Dimas”“) at ”http://www.projectsandimas.com/">http://www.projectsandimas.com/.

The eBay Desktop is an Apollo Application, oops, Adobe AIR application, that is developed by our friends Tony Hillerson and Sean Christmann from EffetiveUI for eBay. As they had their hand full applying the finishing touch to the beta, they asked Lee and myself to help with the beta Signup program and administration site which is a Ruby on Rails application. How cool is that! Thanks guys for the opportunity to work on such a visible project…

Now if you know Sean you will understand why using the eBay Desktop is fun. When Sean is not coding he is playing games, and he want’s any application to be fun and playful. Even when he gives talks he manages to demonstrates how to program a WII controller. It’s cool that Alan Lewis gave them the creative freedom to create some new user experience concepts on top of the existing eBay apis.

Ken, my desk neighbor at one of my clients asked why would you need something like Adobe AIR? Well in the case of the eBay Desktop, you are provided with an immersive experience, having a dedicated application will encourage the user to stay within that application and not get (too) distracted. The desktop also allows to save custom searches and additional information locally, thus providing functionality that may not be available by the existing eBay apis. It could also allow for functionality like drag&drop of images and text from the file system to create online auctions, use a connected camera to snap pictures, scan bar codes to retrieve product information, and so on…

20070620_eBayDesktop.jpg

PS: Hey Sean what’s your blog…or are you too busy coding?

Posted by Daniel Wanja Thu, 21 Jun 2007 01:01:45 GMT


Free Rails Training

From my perspective (as someone who has been doing Rails development full time for the past two years or so) it’s hard to believe, but there still are web developers who aren’t familiar with Rails. I was recently approached by an old friend about doing a training session on Mono. The last time we had been in close contact, I was exploring Mono and excited about the possibility of a .NET environment on Linux. Of course, that was before I discovered ActiveRecord and became a card-carrying Rails fan club member.

I told him that while that would probably be fun, I’d rather talk about something I didn’t have to learn for the presentation, and by the way, had he ever considered having a session on Rails? Well, I’m just back from the first segment of the course, which consisted of installing a Rails development stack in an Xubuntu virtual machine. Due to bandwidth limitations and a delayed start, that was all we accomplished tonight, but the remainder of the course (actually learning about Rails) will be in two weeks. We will provide a ready-to-go virtual machine to anyone interested in an introduction to Rails, and there are a few seats still available.

So if you or someone you know will be in the Denver area at 6:30 on June 28 (the day before the iPhone!), and have a couple of hours to be indoctrinated introduced to Rails, drop me a line [my gmail account is rubysolo].

Posted by Solomon White Fri, 15 Jun 2007 05:34:00 GMT


Bloated RailsConf Presentation Downloader

I’ve updated my downloader from earlier to include all sorts of fancy options. It no longer requires wget, it just uses open-uri. It can give the files a fancy name. It can be told where to download the files to. It will skip files that won’t download for some reason. It will even butter your toast if you can find the correct command line switch.

It’s about 3 times bigger than the previous one. But maybe you can learn a little more about optparse, hpricot, file handling, and error handling along the way.

Here it is:

#!/usr/bin/env ruby

require 'optparse'

OPTIONS = { :Verbose => false,
            :Force => false,
            :DownloadDir => '.',
            :DescriptiveFilenames => true
          }
OptionParser.new do |opts|
  opts.banner = "Usage: #{$0} [options]"

  opts.on("-v", "--[no-]verbose", "Run verbosely, default #{OPTIONS[:Verbose]}") do |verbose|
    OPTIONS[:Verbose] = verbose
  end
  opts.on("-f", "--[no-]force", "Force downloads, default #{OPTIONS[:Force]}") do |force|
    OPTIONS[:Force] = force
  end
  opts.on("-d", "--[no-]descriptive", "Use long descriptive filenames, default #{OPTIONS[:DescriptiveFilenames]}") do |long|
    OPTIONS[:DescriptiveFilenames] = long
  end
  opts.on("-p", "--path PATH", "Path to download to, default #{OPTIONS[:DownloadDir]}") do |path|
    OPTIONS[:DownloadDir] = path
  end
  opts.on_tail("-h", "--help", "Print help message") do |help|
    puts opts
    exit
  end
end.parse!

require 'rubygems'
require 'hpricot'
require 'open-uri'
require 'fileutils'

BASE_URL = 'http://www.web2expo.com'

def log(str)
  puts str if OPTIONS[:Verbose]
end

def download(href, filename)
  url = "#{BASE_URL}#{URI.escape(href)}"
  download_file = File.join(OPTIONS[:DownloadDir], filename)
  if OPTIONS[:Force] || !File.exists?(download_file)
    log "downloading #{File.basename(href)}..."
    begin
      File.open(download_file, 'w') { |f| f.write(open(url).read)}
      log "\tsaved as #{download_file}"
    rescue Object => e
      FileUtils.rm(download_file)
      $stderr.puts "ERROR downloading #{url}: #{e.message}"
    end
  else
    log "skipping #{File.basename(href)}... already downloaded as #{download_file}"
  end
end

FileUtils.mkdir_p(OPTIONS[:DownloadDir])
h = Hpricot(open("#{BASE_URL}/pub/w/51/presentations.html"))
h.search('div.presentation').each do |presentation_node|
  href = presentation_node.at('a[@href^="/presentations/rails2007/"]')[:href]
  if OPTIONS[:DescriptiveFilenames]
    name = presentation_node.at('b a').inner_text.strip
    text = presentation_node.inner_text
    speaker = text[/Speaker\(s\):\s+(.*)\s*$/, 1]
    date = Date.parse(text[/Presentation Date:\s+(.*)\s*$/, 1])
    filename = [speaker, date, name, File.basename(href)].compact.map { |s| s.to_s.strip.gsub(/[^\w\.]/, '_').squeeze('_') }.join('-')
  else
    File.basename(href)
  end
  download(href, filename)
end

Posted by Lee Marlow Mon, 21 May 2007 22:49:00 GMT


Download RailsConf 2007 Presentations

Updated: Now more bloated!

Run this to get the RailsConf 2007 presentations:
#!/usr/bin/env ruby

require 'rubygems'
require 'hpricot'
require 'open-uri'

base = 'http://www.web2expo.com'
h = Hpricot(open("#{base}/pub/w/51/presentations.html"))

h.search('div .presentation > a[@href^="/presentations/rails2007/"]').each do |a|
  url = "#{base}#{a[:href]}"
  if File.exists?(File.basename(url))
    puts "skipping #{url}... already downloaded"
  else
    puts "downloading #{url}..."
    `wget --quiet #{url}`
  end
end
I might clean it up more later to name the files better and not use wget, but this was quick and easy... not to mention a way to use everyone's favorite parsing tool: Hpricot.

Posted by Lee Marlow Mon, 21 May 2007 18:27:00 GMT


Will Marcel Molina Steal Matz's Ruby Super Powers

I didn’t start watching Heroes until after I heard Rich Kilmer and Marcel Molina talking about it while putting the badges together for RubyConf 2006 in Denver.  Had I watched it before maybe I would have been a little scared of Marcel (Sylar), but he was very nice and didn’t seem like a threat to the Ruby world at all.

So, why be scared of Mr. Molina? You be the judge.

class MarcelMolina
  include Heroes
  
  def <=>(other_hero)
    other_hero.name == 'Sylar' ? 0 : 1
  end
end

== # => true

Posted by Lee Marlow Fri, 18 May 2007 18:02:00 GMT


RailsConf 2007 - Day 2

Note: Check out the RailsConf Wiki and the presentation page

Chad Fowler is starting the keynote introduction. 1600 developers are at the keynote. He makes a passionate speech about how Rails is changing how we think about software and how Rails impacted the industry. An now Rich Kilmer introduces the person that introduced him to Textmate: DHH.

A peek at Rails 2.0

Celebrating what we have

  • > 1 million downloads
  • Hundreds of plugins
  • ~10k people on rubyonrails-talk
  • He asks who is getting paid in one form or another using Rails and a large part the participants raise their hands.
    ( Books: many Rails books in many languages. Surpassed PHP, Perl and Python (source O’Reilly Radar).
  • http://workingwithrails.com/ indicates over 100 countries where people do Rails.
  • IDE: CodeGear, Textmate, NetBeans, JetBrains, Aptana

Rails 2.0

  • It’s not gonna change everything you know, it’s gonna be humble.
  • No new ‘great’ idea.
  • The experiment worked! (RESTFul resource)
  • The world of resources is a better, greener place.
  • Rails 2.0 will focus more on the REST convention
  • Routes
map.namespace(:admin) do |admin
  admin.resources :products,
    :collection => {:inventory => :get},
  :member => {:duplicte => :post},
  :has_many => [:tags, :images, :variants],
  :has_one => :seller
end
  • David now demos the new scaffolding that use the resource approach of working with things.

./script/generate scaffold persone name:string create_at:time

  • He adds new format format.csv to support exporting as comma separated text.
    You can easily connect to this services:
    require 'active_resource'
    class Person < ActiveResource::Base
      self.site = "http://localhost:3000"
    end
    p = Person.find 1
  • Beyond CRUD you can custom methods, Person.find :all, :params => {:name => ’d’}
  • This all works today.
  • Action Web Service is no longer service with Rails 2.0. ActiveResource is.
  • Friends and allies: Ajax, REST, Atom, OpenID

9 other things I like about rails 2:

1) Breakpoints are back (ruby_debug)

2) HTTP Performance

<!-- :cache => true
     gzips all javascript and stylesheet in one file 
     i.e. prototype, css get zipped down to 35K from 200k
-->
<%= javascript_include_tag :all, :cache => true %>  
<%= stylesheet_link_tag :all, :cache => true %>  

3) Query cache. DHH loves free performance

4) action.mime_type.renderer

people/index.html.erb
people/index.xml.builder
people/index.rss.erb
people/index.atom.builder
def index
  respond_to do |format|
    format.html
    format.xml
    format.rss
    format.atom
  end
end

5) config/initializers. One file per configuration in initializers folder

6) Sexy migrations (just nicer)

create_table :people do |t|
  t.integer :account_id
  t.string :first_name, :last_name
end

7) HTTP Authentication. authenticate_or_request_with_http_basic

8) The MIT assumption. ./script/generate plugin now generates a default MIT license file.

9) Spring cleaning. Deprecated features of 1.2 will be removed. In-place editor will be moved to plugins.

That’s pretty much it. Thank you.

Building Community Focused Apps with Rails by Dan Benjamin

Rails is the ideal platform for Web 2.0. Fast prototyping and proof of concept. Prototype becomes the product. Conducive to collaboration with developers and designers. Dan is going to talk about Cork’d. Currently 20000 users.

Make a Plan.

  • Treat your application like a product and your idea like a business. Just because it’s a good idea doesn’t mean it’s gonna be automatically successful.
  • Stay Agile. Resist big infrastructure.
  • Build the Right Team. Keep it light.
  • Determine Ownership.
  • Have a Revenue Stream (ads don’t count)
  • Focus on Simplicity. Don’t build features just because you think they are cool.
  • Don’t Release a Public Beta. They had two private betas. They learned from a handful set of people rather than from a large group.
  • Know Your Audience. Be your Audience

Build the App.

  • Think Like a Designer.
  • Consider the Fold.
  • Avoid Big Migrations. User entered data can be challenging.
  • Collaborate.
  • The Rails Layouts Makes Designers Happy.
  • Common Rails Collaboration Tools. Subversion, Capistrano, Campfire, Basecamp, Lighthouse.
  • Don’t Repeat Yourself: Use Plugins. acts_as_authenticated, attachment_fu, acts_as_taggable, exception_notification, open_id_authentication, ymlr4r geocode
  • Take “Code Vacations”

Get Noticed

  • “It’s Google’s World, We Just Live in It.”
  • Use Smart URLs. /wine/view/5748, /authors/danbenjamn
  • Leverage Markup. Google reads metatags.

Recruit Members

  • Make It Obvious and Easy to Signup
  • Ask Only for What’s Truly Necessary
  • Ask for Everything but Require (Almost) Nothing
  • Limit Non-Members

Keep Them Coming Back for More

  • Make Frequent Improvements
  • Respond Positively to Your Members
  • Create A Developer Network
  • Share Your API
  • Find Good Partners
  • “If You Do Things Right, People Won’t Know You’ve Done Anything At All.”
  • Just Ship It

How We Used Apollo and Rails to (start to) Build an Agile Project Management App by Christopher Haupt and Chris Balley

They are part of Adobe’s Consumer Hosted Applications and Online Services group. They use whatever technology is right for the job, Flex, Rails and dozens of other technologies. They use Scrum and are geographically dispersed teams, in Germany, India, US.

Why Did We Choose Apollo and Rails?

  • Learning Exercise
  • Offline Support
  • Maturing Tools
  • Leverage our Rails Experience
  • Cross Platform
  • Installers

Why not AJAX?

  • Offline and Partially Connected
  • File System Access
  • Drag and Drop with Native OS

Now they are demoing Maptacular, an Apollo applications.

Combining Apollo and Rails: Communication

  • Flash Side
    • AMF
    • SOAP
    • REST <== they used that
  • HTML Side
    • AJAX techniques
  • Hybrid
    • Ue DOM bridge to use the one you are comfortable with.

Combining Apollo and Rails: Quirks

  • Flex’isms
  • RESET can be a pain
    • Use _method hacks for PUT, DELETE, HEAD
    • Pass a body on everything other than GET
  • Some HTTP headers can’t be used, or problematic on a GET
  • HTTP Status codes not accessible
    • Use URLoader to get HTTP Status Codes
  • dasherize-is-unhealthy-to-your-actionscript-code
  • Migrating to newer Apollo Builds
    • ApolloApplication .vs. Application (for transparency)

Now they move on to Code Snippets. The sample code can be found on the Apollo Labs.

  • Online/Offline (Event.NETWORK_CHANGE). Notifies if network change but doesn’t tell if network is up or not. Solution: use URLoader to ping the network (they ping google.com)
  • Video Capture, File IO, Doing your own Chrome

Chris now demonstrate some community create applications.

Posted by Daniel Wanja Fri, 18 May 2007 16:35:00 GMT


RailsConf 2007 - Day 1

Here we go, RailsConf 2007, has started. It’s bigger than ever, more tracks, more sessions. This is the first day where they provide full or half-day tutorials sessions. I will try to cover the different sessions I will attend so stay tuned.

Today I will attend: “Scaling a Rails Application from the Bottom Up.” and “Harnessing Capistrano.”

Scaling a Rails Application from the Bottom Up. by Jason Hoffman

Jason Hoffman, CTO of Joyent. Did also form Textdrive.

Six part presentation:

I. Introduction and foundation
II. Where do I put stuff
III. What stuff?
IV. What do I run on this tuf?
V. What are the patterns of deployment?
VI. Lessons learned

His presentation will answer the following questions:

  • What is a “scalalble” application?
  • What are some hardware layout?
  • Where do you get the hardware?
  • How do you pay for it?
  • Where do you put?
  • Who runs it?
  • How do you watch it?
  • What do you need relative to an application?
  • What are the commonalities of scalable web architectures?
  • What are the unique bottlenecks for Ruby on Rails applications?
  • What’s the best way to start so you make sure everything scales?
  • what are to common mistakes?

Maybe it’s a little early, or I am not awake, but the talk seems a little slow. But Jason seems to do a good job at describing how the different people (developer, sysadmin, …) see scalability.

Ease of management is on log scale. It’s not just a Rails issue. A $5000 Dell 1850 costs $1850 to power over 3 year.

This is a really good presentation from a point of view of what is involved to build data center. I should have read better the description of the presentation.

So I am going to move over to Thomas Fuchs presentation:

Is JavaScript Overrated? Or: How I Stopped Worrying and Put Prototype and script.aculo.us to Full Use by Thomas Fuchs

I am just tuning in to his presentation and he is showing of how to use selectors with Prototype.

DOM traversal:

$('blech').previous('ul').down('.somesuch',2)
$('homo-sapiens').descendantOf('australopothecus')

Element methods:
$('a_div').update('blah').show().setStyle({opacity:0.5});
$('myform').focusFirstElement();
$('person-example').serialize();
Element.addMethods('form') {
  valid: function(element) {
       // code to valid form
  }
}

What’s new in Prototype 1.5.1:

  • speedier $$
  • CSS 3 Selectors
  • $(‘form’).request()
  • String .includes .times .toPaddedString(8,2)
  • JSON support i.e. new Date().toJSON();
  • $(‘blah’).firstDescendent()
  • throw $continue deprecated use “return” instead
  • Safari issues fixed
  • YAML compatible

DOM, Events, Forms, Position:

  • new Element(tagName, attributes);
  • $(‘blech’).insert(html|object, position)
  • $(‘blech’).wrap(‘span’);
  • $(‘country’).setValue(‘AT’);

Function.prototype: curry(), wrap(), defer(), delay()
Q: When is the next release of Prototype?
A: When it’s ready.

A 10 minute break now, the Thomas is going to present Scriptaculous Effects.

script.aculo.us adds advanced User Interface interaction to the DOM. Extracted from Real-World applications. Started with Fluxiom. The two main parts are Visual effects and Drag&Drop. Today we will only look at the Visual Effects. They are other parts such as Autocompleter, In-Place Editor, Slider control, DOM Builder, and Unit testing. They won’t be more advanced components.

Effects engine: the ideas behind the engine is timeline based animations.

Core Effects:

  • Effect.Move
  • Effect.Opacity
  • Effect.Highlight
  • Effect.ScrollTo
  • Effect.Morph // 1.7+
  • Effect.Parallel

Based on the Effect.Base.prototype class.
Effect life cycle: intialize(), setup(), update(), finish(). Each frame calls update().

Effect.DefaultOptions = {
  transition: Effect.Transitions.sinoidal,
  duration: 1.0,
  fps: 100,
  sync: false,
  from: 0.0,
  to: 1.0,
  delay: 0.0,
  queue: 'parallel'
}

Morphing: came out with Scriptaculous 1.7.

$('mydiv').morph('font-size:20px; color:"#abcdef");
$('mydiv').morph('warning'); //limited to top level classname

TimeLines:

new Effect.Blah('element_2')
new Effect.Blah('element_2', {duration:0.6, delay:0.3});

You have to be careful with effects created that will run in parallel as the javascript engine are not multi-thread. Better solutions is to use queues:
new Effect.Blah('element_1', {queue:'end'});
new Effect.Blah('element_2', {queue:'front'});

and use scope:
new Effect.Blah('element_1', {queue:{scope:'blech'}});
new Effect.Blah('element_2', {queue:{scope:'blech', position:'end'}});
new Effect.Blah('element_3', {queue:'front'});

Utilities:

Element.toggle('element', 'blind');
Element.tagifyText(element);
Element.multiple('element', Effect.Fade, {speed:0.05});

Do it yourself: Thomas now shows how to create an Effect programatically.

Future features:

  • Sound without Flash (it’s already in the beta release). Sound.paly(‘sword.mp3’). It uses native sound implementation with Quicktime as fallback.
  • Adjust to new Prototype features. $(‘blech’).fade(); $(‘blech’).slowlyReveal();

Part IV: Testing

Thomas is flying through testing…

  • assert(true)
  • assertEqual(expected, actual)
  • assertEnumEqual(expected, actual)
  • assertNotEqual(expected, actual)
  • assertMatch
  • assertIdentical
  • assertNotIdentical
  • assertType
  • assertRaise
  • assertRespondTo
  • assertVisible(element)
  • assertNotVisible(element)
  • info(message)

Mostly unit testing, but some functional testing is available.
Most assert take a message. I.e. assertXYZ(params, message)

  • wait(milliseconds, method) // should be last statement in test, but can be nested.
  • rake test:javascripts (browser will popup). Done with the javascript_test plugin. Launches the web server (WEBrick), then controls the browsers (Safari, Firefox, IE), the browser then calls the web server, and list the results (SUCCESS, FAILURE, and ERROR)

Resources:

JRuby talk by Charles Nutter and Thomas Enebo

(note taken by Robert Hall, thanks man!)

  • 1.8ish—based on Ruby 1.8.5
  • Gems 0.9.1 is pre-installed
  • Partially compiled—about 80% of Ruby code compiles…rest is run in JIT mode
  • Ruby 1.8 strings supported. Works with ActiveSupport::MultiByte
  • Ruby 2.0 String support coming
  • Most Ruby apps should work on JRuby
    —most gems just work
    —Red Cloth, Blue Cloth
    —Hpricot
  • Typical Rails commands just work
  • ports: Mongrel ported, Hpricot ported, RMajick in progress
  • Ruby thread API supported
    - native-threaded 1 JRuby thread=1 system thread
    -
    supports thread pooling
  • performance comparable to C Ruby impl
    —Rdoc has issues
    CLI performance slow
  • JDBC support strong
    —mySQL support strong
    —some postgres issues
    —some Oracle users
    —many others
  • ActiveRecord JDBC
  • No native extension support
  • Goldspike—JRuby deployment tool
    —Rails plugin for building WAR files
    —app server agnostic
    —Can be deployed to Java app server as WAR file
  • Deployment— MOngrel supported..some issues (forking, process management doesn’t work)
  • Access to Java EE features (JMS, JPA, JTA)
  • Java libraries can be wrapped
  • Coming soon
    —A Grizzly/GlassFish V3 option
    —Lightweight, gem-installable like Mongrel
    —Concurrency, pooling mulit-app like WAR
  • Mephisto demo
  • Main idea—- Ruby as the programming language, Java for the platform and libraries
  • Best of all worlds
    -Ruby or Rails as the appl layer
    —Java libraries alone or as ported/wrapped gems
    —Java based services
    -legacy app integration
    —The JVM
  • Acceptable to today’s enterprise
    —Java to ‘them’, Ruby to you
  • Calling Java from Rails demo
    RSS reader demo..calling Java library from Rails code
  • Tools—
    Textmate, Emacs, Vi(m), notepad
    - missing some features
    -
    code competion?
    - jump to declaration?
    -
    rename variables?
    — popup Rdoc?
  • Presenters claim Best Ruby IDE Available is NetBeans (milestone 9)
    - code completion
    -
    smart syntax highlightings (for Ruby code, RHTML files, etc)
    — Rdoc support
  • Demoed a cool Ruby shell like IRB implemented in Swing..built into NetBeans
  • Jruby 1.0 almost ready

LUNCH: will be back at 1:30pm

Harnessing Capistrano by Jamis Buck

Jamis will focus Capistrano 2.0 today. Some things will not be backward compatible with Capistrano 1.0.

His slides are online at http://presentations.jamisbuck.org/railsconf2007/.

Posted by Daniel Wanja Thu, 17 May 2007 16:04:00 GMT