CanadaOnRails, day 2, shared notes
Published 2006-04-17 @ 23:57
Tagged rails, thoughts
(sorry this took so long to get out, but Whistler doesn’t have good (free) intarweb)
Canada On Rails, day 2.
Same as before, after the cut…
=====
Day 2
=====
---------------------------------------------
Thomas Fuchs - Advanced Rails AJAX techniques
---------------------------------------------
(Talk is based on Prototype 1.5)
Enumerables in js are cool. So are $ (fetches DOM object, given id) and $$ (fetches an array of DOM elements, given CSS selector).
Direct Element extensions
if ($('foo').visible())
$('foo').hide();
Events
- Visual effects
- If it's used right, it's more than eye-candy. "It's a really good thing."
- Drag and Drop
- Ready-to-use controls
- Plus some extras (javascript unit testing, DOM builder)
On-the-fly JavaScript:
Rails javascript Template
Rails AJAX: A history
Thing(y|ies) Time
-------------------------------------------------------------------------------
Ideas to make the web snappier Late 20th century
Prototype 1.0, Rails Helpers Rails 0.11, March 22, 2005
Prototype 1.3, script.aculo.us Rails 0.13, July 6, 2005
Prototype 1.4, script.aculo.us 1.5 Rails 1.0, December 13, 2005
and another entry that I missed...
RJS - dynamic javascript - no javascript programming necessary
Do it in Ruby, like everything else in Rails
page[:cart].update render(:partial => 'cart')
page.select('p.hint').each do |hint|
hint.visualEffect :highlight
end
Generates javascript:
$('cart').update('...rendered partial...');
$$('p.hint').each(
function (value, index) {
value.visualEffect('highlight');
}
};
blah action gets called
blah.rjs generates javascript
> this is pure ruby
prototype sees text/javascript and evals JavaScript
don't think about javascript, think of it as magic
Sam Stephenson is the magician (Thomas Fuchs is the sidekick)
page.replace :list, render(:partial=>'list')
Element.replace('list'...);
page.replace_html :list, ...
- same as -
page[:list].update ...
Staying DRY
page[:list].reload
Refreshes contents of element "list" with the partial of the same name
select in ruby (rjs) == $$ in prototype.
Pluck
page.select('p.hint').pluck('t', 'offsetTop');
creates a javasacript "t" variable from the pluck list?
Arrays
page.select('p.hint').find_all('h') do
page <<'value.visible()'
end
Creates an "h" variable as an array containing all visiblt p.hint elements
Style
page[:blah].set_style :backgroundColor => '#F00'
page[:blah].set_opacity 0.5
creates javascript to do the same
First Element
page.select('p.hint').first.hide
Visual Effects
page[:blah].visual_effect(
:pulsate, :duration => 4.seconds)
Other visual effects:
?apper, fade, slide_up, slide_down, blind_up, blind_down, pulsate, switch_off, puff and more
Render :update (controller-based)
def update
render(:update) do |page|
page.hide :cart
end
end
RJS Helpers
module SomeHelper
def ajaxy_stuff
page.hide :blah
end
end
Call in .rjs
page.ajaxy_stuff
Firefox + Firebug + Web Dev Toolbar
Venkman JavaScript Debugger
Tamperdata
Rules #1 & #2: Use Firefox with extensions
Rule 3: Test with all browsers you want to support
Safari Web Inspector
http://webkit.opendarwin.org/blog/?p=41
(video showing and demo of Fluxiom)
1500 lines total code - about the length of your average Java XML config file
Web 3.0
blog.fluxiom.com
launching in April 2006
-------------------------------------------------
James Adam - Engines: Team Development with Rails
-------------------------------------------------
slides posted at:
http://www.rails-engines.org/presentations/yvr06.pdf
Common functional aspects:
* Authentication, etc.
* especially so within a domain
examples: user control, reporting, charts and graphs, data storage content management auditing, help systems, classic enterprise problems
These are BORING problems!
many applications x many aspects = lots of code + lots of maintenance
developers are often lazy and/but concientious
but DHH says - Reuse is overrated
James Adam - agrees <!> "Reuse is essential... it just depends on the context"
The context within a given industry allows you to reuse solutions, and prevents you from going insane.
An example here is a help system
Procedure, make a generator for an application, package as a gem, and distribute the gem.
What happens when there is a bug or a new feature in the future. Does this bug now need to be fixed in every application??
- could build a patch and install it on 20 apps x every aspect of those apps.
- could repackage the patched version and redist the gem - this is better, run the generator
It's not so simple, because the generator (vendor) code will be customized For instance one customer might want a method that creates a summary of the help topic.
generators are difficult to maintain, because you customise the code.
use generators instead of code patches
hard to seperate specific logic vs general logic
no way to isolate application spec changes from the basic system
We need separation between boring standard code and the specific stuff in your implementation.
"rails 1.0 happened" - we got plugins!
Anatomy of a plugin
init.rb is run everytime your web app is loaded
install.rb (1.1 feature) evaluated immediately a plugin is installed (example: create directory) only evaluated once
lib (folder) automatically loadable file under this directory (required by rails without us requiring them explicitly) added to $LOAD_PATH
Plugins are in one folder, they are not mixed into your app.
==Shareable
Because they are self-contained it is easy to share within a team, or across a community.
Crucial for rails developer using plugin
Sharing with svn:externals (rock - seriously)
3 Applications, 1 plugin that we want to share across all three
Instead of copying the plugin into multiple applications we want some sort of link to the plugin in a single location.
svn propset svn:externals 'my_plugin svn://server/my_plugin' vendor/plugins
This links the same source for the plugin (in it's own repository) into all three applications, not a copy. Therefore, if we make a change to the plugin and want to propogate it, all you need to do is:
svn update vendor/plugins - it pulls all the externals
"PLEASE PLEASE USE SVN.. and use externals for your plugins."
You can use svn:externals to track specific Rails releases in your vendar/rails directory - this locks you into a specific version which is necessary for deployment
svn:externals is MASSIVELY IMPORTANT
If we find a bug we just need to fix and run svn update once
Files in plugin dir:
help.rb - model
help_helper.rb - helper
help_controller.rb - controller
hard_to_share {
show.rhtml - view
help.css - public files
001_add_help.rb - migrations
}
there is no way to easily share views , same thing for css or js or migrations - plugins don't work for these
we can only share code with plugins
ENGINES:
(login enginer bane of my life - funny)
login engine is what engines are it is just an example
refutes propaganda about engines
engines are plugins but a little more
a mechanism for sharing MVC slices between your application including view, controller, migrations, public assets (css, images) everything
no need to relearn arcane file system same as rails file structure under the plugin directory
It is not a tiny application inside your application. You put a full aplication in there but it would be incredibly hard and, likely, incredibly stupid.
from backchannel: {
David H:
I actually think that engines as james talks about them are not truly evil
Engines are potentially cool for in-company sharing
}
engines are not standalone applications
engines are stored same place as plugins are (vendor/plugin/my_engine/
/models
/view
/controller
/db
...etc
from backchannel: {
David H.
I think this is where the evil begins
That the assumption is that you should share it on the internet
}
but we don't use init.rb instead init_engine.rb
script/generate engine Help
engines predate plugins
ridiculously simple, take a loook
http://svn.rails-engines.org/plugins/engines/
completely compatible with all the version of rails
engines are best used for sharing code between your own applications.
intra-company usage.
David H.
there's no auto-namespace
if you overwrite, you overwrite
that's a feature, though
allowing you to customize the engine
engines plugin is opinionated open source
issues and patches go to
dev.rails-engines.org
propaganda
www.rails-engines.org
docs
api.rails-engines.org
David H.
Just don't share it with the world
David H.
Right
David H.
Engines is a power feature for YOUR applications
----------------------------------------------------------------
Geoffrey Grosenbach - Generating Great Graphs with Ruby on Rails
----------------------------------------------------------------
nuby on rails.
http://nubyonrails.com/
http://topfunky.net/
Gruff!
gnuplot
(http://rubyforge.org/projects/rgplot/)
* can do very complex stuff, bars, 3d plots, meshes, whales <!>
* animation
* a gem exists for this on rubyforge
* fairly simple interface, lots of capability
* gem install gnuplot.
MRPLOT < mister plot?
(http://rubyforge.org/projects/mrplot/)
* sinewaves, complex graphing
* but can it do whales?
* need imagemagick, and rmagick
* this is written in ruby so you can hack it easily
* a bit more simple than gnuplot, but hte code can get complex
* uses a very OO approach to breating graphs
Sparklines Graph library for Ruby
(http://rubyforge.org/projects/sparklines)
* Sparklines were created by Edward tufte
* sparklines are word sized graphs
* It made Geoff famous, got a lot of attention
gem install sparklines
Gruff graphs
http://nubyonrails.com/pages/gruff
gem install gruff
require 'gruff'
http://topfunky.net/svn/gruff/
* line graphis, bars
* can change colours and fonts, put images in the background
* 'radar' or 'spider' graphs were contributed.
color scheme widget from firewheel design is useful
The code example for generating graphs with Gruff is very succinct
recomends:
caches_page :popularity
def popularity
g= Gruff::Line.new...
.....
end
If you pull up points.png it will still cache it as an html file and your browser won't like it.
Use builtin rails helper to make image tags
<%= image_tag url_for(:controller => 'report',
.....
file will have png appended and be cached correctly.
You can use named routes
map.report 'report/:action/:id/image.png',
:controller => 'report'
<%= image_tag report_url(:action => 'popularity',
:id => 5) %>
This will generate a nice pretty url: /report/popularity/5/image.png. If you don't do it this way, you either have to add something.png|gif|jpeg to the end of all your graph links, or else when people download them they won't have a file extension. Which is tres annoying.
This is an example of how easy it is to pull data for a graph:
articles = Articles.find_all
g.data "Comments", articles.map { |article|
article.comments.count
}
yarr. beware the rough underbelly.
http://roughunderbelly.com/user/login
Rough underbelly is a site Geoff has done that does some nice stuff with gruff and with sparklines.
Dimewise - did some nice stuff with gruff
http://www.dimewise.com/
Mood-o-meter - graphing personal health and well-being
http://morale.erikbenson.com/account
graph your caffeine vs mood!
Bellygraph - graphing personal goals
animated graphs
using ajax animated sliders can regenerate graphs.
Future applications of rails and graphics - chainging the sky on a weather site, or based on time of day that you visit a site. (http://1976design.com/blog/ used to do this). putting different elements together on layers and creating graphics.
Geoff is thinking about these non-linear ways of displaying information.
-----------------------------------------------------------
Robby Russell - Sneaking Rails through the (Legacy) System
Founder of PLANET ARGON
-----------------------------------------------------------
slides posted at:
http://www.robbyonrails.com/articles/2006/04/14/sneaking-rails-through-the-legacy-system
Using Rails with a Legacy DB
"Anything before Rails is a legacy system"
* Built in an *old* programming language
* Something you *inherited*
* A *valuable* asset to your company
..They said it couldn't be done.
Extending the legacy system
there's a lot of data out there.
-meet the damands of today's market.
-what do you do when your pointy haired boss says to get that data to his pda (when he's at a hash bar in Amsterdam)
-Existing data is highly vaulable.
80% of it systems are legacy.
==Options:
migrate the database.
why?
-if old db is slow.
-if need to get out of expensive licenses
==web services (topic jump?)
nice because:
- Interacting with web services is nice because they have open standards.
(SOA)- ws-deathstar.
- Data over http:
==Encapsulating the Legacy Database
- Pure SQL approach with a database adapter
this is not fun, with roR you have....
- Persistince framework in ror, is handy.
you don't have to be an SQL wizard.
==Database abstraction layer
How do we do this in rails?
Active record, can use it to interact with the legacy system.
Active Record << Legacy
Acts as Leagacy, Robby's plugin
for interacting with non-rails-convetional table and column names.
designed to get your legacy db up and running with rails.
This lets you handle things like column or table prefixesvery easily so your code can still be a lot more railsy without
Dell DVD store problem
http://linux.dell.com/dvdstore/
PostgreSQL download ...
There are some cool sample databases here you can stress test your stuff with.
http://pgfoundry.org/projects/dbsamples
Robbie is doing some live coding here to make a database work with rails
categories table and a products table
uses acts_as_leacy to specify the table name and primary key name, Robby is huge on script/console
Array datatypes (serialize arrays to DB? or encompass multiple rows?)
Still has problems with stored procedures, activerecord doesn't handle that in its current state
Q: Instead of denormalizing witha table in the middle, what if there was a table with columns, item1, item2, item3, item4, item5.
A: no solution for that yet.
Robby will be posting more about acts_as_legacy on his blog shortly.
resources and links.
http://wiki.rubyonrails.com/rails/pages/HowToUseLegacySchemas
http://wiki.rubyonrails.com/rails/pages/HowtoUsePostgresViewsAsTables
http://api.rubyonrails.com
http://www.agiledata.org
http://robbyonrails.com
http://www.planetargon.com
martin fowlers bliki:
http://www.martinfowler.com/bliki/
-----------------------------------------
Jeremy Voorhis - Internationalizing Rails
-----------------------------------------
== What is Globalization
* Internationalization
* Localisation.
== I18N
* Preparation of software to be useful in multiple locales
* concerns. strings may be bi-directional
* dates, times, currency (commas or periods)
== L10N
* translated content for a language
* designs from right -> left or L-.R
* Formatting dates, times and numbers for a specific region
* content that is sensitive to your audience's culture.
significance of colours, etc.
== Unicode
* unpopular in japan, and not natively supported in ruby.
since unicode had Han unification, which was unpopular in Japan, many Japanese coders prefer JIS which has more acceptable support for japanese characters
* Support available through jcode module
require 'jcode'
$KCODE = 'u'
database must support unicode too.
== Locales
* Operating definition: a combination of a language and a region
* can be identified with a locale tag
RFC 3066
LANGUAGE TAG = PRIMARY SUBTAG *( "-" Subtag)
Primary-subtag = 1*8ALPHA
Subtag = 1**(ALPHA / DIGIT)
primary subtag is an ISO 639 language code and should be lowercase
Subtag is typically an diso 2166 country code and should be capiutalized
eg en-US
fr-CA
es-419 <-- latin american spanish.
== Globablize
* supported through the globalize plugin
Model translations
View transations
Date, time, number formatting.
== Getting started with globalised
svn.globalize-rails.org/svn/globalize/globalize/trunk/
239 languages 189 countries
$ plugin install http://svn.globalize-rails.org/svn/ globalize/globalize/trunk
$ rake globalize:setup
== Setting the Base Language
#Include yor applic ation configuratio below
Local.set_base_language 'en-US'
== Capturing Locales.
map.connect ':locale/:controller/:action/:permalink'
Settign an active locale
in your ApplicationController:
before_filer :set_locale
This sets your locale, but you can modify the controller to fall back.
class Feature < ActiveRecord::Base
translate :headline, :abstract, :body
end
doing it: acts as a method!
<%= 'FEATURES'.t -%>
or
<%= :title.t -%>
There is a translation availability helper.
so you can say ' translation not available'
Showed lots of code examples....
Showed some examples of planet argon work with simple admin interfaces for translaters to use.
http://rashgash.co.il/en
Also showed israeli guitar store, Joshua Harvey coded it, and was the founder of Globalize, the text is reversed because hebrew is R->L.
www.globalize-rails.org
* Trac
* Wiki
* Mailing list
globalize.rubyforge.org
* API Docs
Joshua Harvey
http://shnoo.gr/
Joshua Sierles
http://diluvia.net/
www.jvoorhis.com
www.planetargon.com
Q: managing a css or image swapping through globablize?
A: Yeah, that might be doable.
Q: can we manage different formats like postal codes
A: it could, the work has not been done yet on this
all slides available as pdf from
http://www.jvoorhis.com/articles/2006/04/14/globalizing-rails-in-yvr
-----------------------------------------------
Sebastian Kanthak - Plugging in with FileColumn
-----------------------------------------------
Sebastian started the presentation taking a picture of all the apple laptops, it was crazy to see so many
Outline:
1. Introduction
2. Features
3. Extending Rails with Plugins
4. ???
5. Profit!
A rails plugin to make file uploads easy?
What's hard about uploads?
- Where to store the files.
- Store as BLOB (binary large object) in db or as regular files?
- File system is better! opinion.
- How to redisplay forms?
- What do you do with images?
- resizing - there is some support for this.
Fuck You.t # => Fick Dich
Store uplaods in filesystem
Handles for mesidaplays
Validations
Uploading images: RMagick
filename stored in the database.
in your schema
create_table :entries do |t|
t.column :image, :string # <-- filename
end
File structure examples:
public/entry/image/1/railroad.jpg
public/entry/image/2/hello.png
public/entry/image/42/yes.gif
public/entry/image/42/thumb/yes.gif
public/entry/image/42/large/yes.gif
file location
/entry/image/:key/filename.jpg
this is done so that filenames dont' conflict
temp files
/entry/image/tmp/
adds validators,
imaage extenstion
image type {image/jpeg}
filesize
uses RMagick
file_column :image, :magick=> {
:crop => 640 x 480
}
does versioning
for regular
thumb
large
etc
does custom transformations - allows you to define yoru own methods that do whatever you want with rMagick.
FileColumn makes file uploads as easy as they should be
Handling images becomes even easier
Q Temp Collects a lot of cruft.
A Make a cron to clean it out.
Dir["public/**/tmp/**/*"].each{|file| FileUtils.rm_rf file} (something like that)
Q How to use another directory
A There's a thing.
FileColumn::ClassMethods::DEFAULT_OPTIONS.update {
:root_path =>
File.join(RAILS_ROOT, "public", "system"),
:web_root = > "system"
}
http://www.kanthak.net/opensource/file_column/
---------------------------------------------------------------------------
Michael Buffington - Using Ruby on Rails to Make a Massive Multiplayer Game
---------------------------------------------------------------------------
His game:
http://llor.nu/
He liked macropoly, which disapeared after some time. It's back but not really good anymore.
Brief WoW demo
WoW has:
* multiple worlds
* items and rewards
* player levels
:WoW = "World of Walking"
"Embrace ADD"
SFI - Single Finger Interface
Minimal Clicks
This game is almost all done with scriptaculous
Heavy use of moveBy() for car movement and gameboard scrolling.
Really Use MVC. He reaolly learned this lesson
Built with:
Scriptaculous
ROR
JSON
SVN
capistrano
JSON is used to move data about.
(http://www.json.org/)
If JSON was/were food, it'd be sushi. Or corn dogs.
Recommendations:
scale later - don't go crazy
he started the application with textdrive
Manage growth
Close the doors, if you want to stop growing for a while.
optimise the obvious
90% Transparency
Open-sourced in October, achieved:
* Massive growth
* burst of development - some sig. contributions
* serious scrutiny from scientists
* damned lies! filthy filthy lies!
* retaining suicidal patients
Future:
* Heavy RJS use
* Open real estate market - let people design buildings
* more like SimCity
* Involving more fanatics
* Simplify the core - refactor
* interface through an aimbot
Make Money
* maybe advertising on buildings.
but he's not committed enough
------------------
Closing Ceremonies
------------------
And so the gathered conference attendies prepared to end thier collective adventure. They nervously
looked around the room, what would become of them after this? Would they ever
see each other again? Where were the doughnuts going to come from??
And what of the bunnies? And the farm, that was promised. Life was not as easy as they had been lead to believe at the outset, but it was clear. It was obvious what they had to do, as they shifted in thier seats, trying to get blood flow through their backsides once more.
There was strained laughter at the antics of the rented talent. Their attempts at humor were modestly appreciated, but mostly for naught. It was painful in a melancholic sort of way.
As each shirt and book was passed off to a lucky winner, the crowd clapped half-heartedly.
The new friends, neigh, the new army, steeled thier collective resolve for the next battle on the field of web development. Even as the last of the prizes were being labouriously handed out by the black clad ladies, there was a single phrase rising from withing the group.... you could almost hear it, 300 people collectively, with one voice, silently screaming, like nothing else in the world mattered or made sense.
Fuck you!
le fin.
-------------------------------------------------------------------------
What's the campfire url again?
https://37s.campfirenow.com/eb527
-----------------------This is the bottom of the file---------------------