Disabling callbacks in an ActiveRecord data migration
January 29th, 2009
It’s often useful to disable ActiveRecord callbacks such as :after_save when migrating data. It’s rather easy to do:
Foo.after_create.clear
Foo.after_save.clear
... migration code ...
If you only need to disable certain actions, it’s also trivial:
Foo.after_save.reject! {|callback| callback.method.to_s == 'some_method_name' }
This sort of thing should never be used in application code, if you’re doing this then your model is broken. However, it’s great for data migrations.
IRC question of the day
January 9th, 2009
Question:
_adc: I'm doing compiling some reports on various database records based in whatever model the user chooses... Is there a better way to figure out which models are in existence than http://pastie.org/356630 ? _adc: I'm looking for an array of all models currently in existence.
Answer:
ActiveRecord::Base.subclasses_of(ActiveRecord::Base)
~/projects/learnhub$ ./script/console
Loading development environment (Rails 2.1.1)
>> ActiveRecord::Base.subclasses_of(ActiveRecord::Base).collect {|c| c.to_s }
=> ["CGI::Session::ActiveRecordStore::Session", "ContactPostCreationNotification", .....]
Three simple scripts for Passenger (mod_rails) management
December 31st, 2008
Phusion Passenger is the best option for hosting Ruby based web apps (anything that uses Rack is compatible). When used with Ruby EE to serve Ruby on Rails applications it will consume up to 33% less memory than other servers such as Mongrel.
Not everything is kittens and rainbows however, as Passenger won’t prevent your app from choking your server if you consume too much memory (via memory leaks in your app, etc). Schedule this script to run every couple of minutes to kill any Passenger processes are consuming too much memory. Passenger will automatically start new ones as needed. You’ll have to figure out for yourself how much is “too much”. In my case it’s 200 MB.
It’s also useful to know how many process Passenger is using, so you can increase the MaxPoolSize when traffic increases. I use Munin to track system statistics and have written two wrappers around the Passenger system tools. The first wraps passenger-memory-stats and the second wraps passenger-status
The result are graphs such as these:

Munin graphs can be extremely helpful when tracking down system performance issues. I highly recommend it.
TexHub: A math equation service
December 29th, 2008
Carsten and I recently launched TexHub which is a little service for serving up latex equations as images. It’s pretty simple, just Base64 + URI encode latex string and append it to a URL. It’s extracted from our math equations feature on Learnhub
For example:
A more complex example: F(x) = \\int_{-\\infty}{a} f(t)dt + \\int_{a}^{x} f(t)dt
We haven’t done much with the front end yet as we’ll primarily be using it as a service, so the focus has been on speed. I wrote the web interface using Sinatra which turned out to be perfect for this sort of app. I plan on writing more micro apps in the future with Sinatra, perhaps the next thing will be the Ruby version of Tilomino which has been sitting untouched for two years….
Irony
August 25th, 2008

Glad to know that MS still considers that IE 6.0 is a ‘recent browser’ (it’s 7 years old, which is ancient in internet years).
Ruby VM shootout on Rock, Paper, Scissors!
August 11th, 2008
Update: I’ve added benchmark numbers for JRuby 1.1.3
I’ve been messing with RubyRPS (Rock, paper scissors) lately, it’s a ton of fun! I thought it might be cool to benchmark the progression of Rubinius, and that little experiment turned into a full blown ruby interpreter shootout. Sure, this is hardly fair since RPS doesn’t use much in the way of complicated stuff (lots of loops over array, etc), but most benchmarks are bullshit anyways. I just want my RPS bots to run fast!
Here are the versions I tested.
- ruby 1.8.6 (2008-03-03 patchlevel 114) [universal-darwin9.0] (macports)
- ruby 1.8.7 (2008-06-20 patchlevel 22) [i686-darwin9.3.0] (macports)
- ruby 1.9.0 (2008-03-01 revision 15664) [i686-darwin9.4.0] (macports)
- ruby 1.9.0 (2008-07-25 revision 18218) [i686-darwin9.4.0] (snapshot 1.9.0.3)
- Rubinius 0.9.0 (ruby 1.8.6 compatible) (ffb998bf5) (08/07/2008) [i686-apple-darwin9.4.0] (from trunk)
- JRuby 1.8.6 (2008-08-07 rev 6555) [i386-jruby1.1.1] (macports)
- MacRuby version 0.3 (ruby 1.9.0 2008-06-03) [universal-darwin9.4] (downloaded binary)
Benchmarking is rather simple:
# time ruby ./run.rb
# time ruby1.8.7 ./run.rb
# time ruby 1.9 ./run.rb
# time rubinius ./run.rb
# time jruby ./run.rb
# time macruby ./run.rb
| Interpreter | Memory Usage | Real | User | System |
| Ruby 1.8.6 | 3MB | 0m36.183s | 0m35.426s | 0m0.241s |
| Ruby 1.8.7 | 10MB | 0m17.778s | 0m17.086s | 0m0.154s |
| Ruby 1.9.0 | 11MB | 1m17.092s | 0m53.843s | 0m22.234s |
| Ruby 1.9.0.3 | 10MB | 0m10.350s | 0m9.911s | 0m0.111s |
| JRuby 1.1.1 | 28MB | 0m18.023s | 0m16.198s | 0m0.417s |
| JRuby 1.1.3 | 28MB | 0m18.622s | 0m17.482s | 0m0.321s |
| Rubinius | 26MB | 0m42.836s | 0m41.556s | 0m0.479s |
| MacRuby 0.3 | 476MB | 0m42.471s | 0m40.302s | 0m0.987s |
How about a threaded run just for fun?
# time ruby ./run.rb --threaded
# time ruby1.8.7 ./run.rb --threaded
# time ruby 1.9 ./run.rb --threaded
# time rubinius ./run.rb --threaded
# time jruby ./run.rb --threaded
# time macruby ./run.rb --threaded
| Interpreter | Memory Usage | Real | User | System |
| Ruby 1.8.6 | 4MB | 1m12.343s | 1m9.703s | 0m0.695s |
| Ruby 1.8.7 | 13MB | 0m18.019s | 0m17.561s | 0m0.188s |
| Ruby 1.9 | 13MB | 1m18.341s | 0m54.516s | 0m21.947s |
| Ruby 1.9.0.3 | 13MB | 0m10.505s | 0m10.013s | 0m0.126s |
| JRuby 1.1.1 | 34MB | 0m17.048s | 0m22.013s | 0m1.890s |
| JRuby 1.1.3 | 31MB | 0m15.630s | 0m22.580s | 0m1.475s |
| Rubinus | 52MB | 0m43.745s | 0m41.893s | 0m0.591s |
| MacRuby 0.3 | Error! | stack level too deep (SystemStackError) |
Conclusion
Ruby 1.9 runs RPS really fast. You may have to compile it yourself for now if you’re on a Mac, since the version in Macports does have some issues. Also, I’d recommend that anyone who is still running Rails apps on 1.8.6 to move to 1.8.7 to for an increase in speed. We’ve been using 1.8.7 to run Learnhub for a few weeks now and have noticed a decrease in memory leaks as well. Be sure to check for compatibility with your Rails app though, 1.8.7 doesn’t work with some older versions of Rails.
Surprises
I was surprised that Jruby did so well. It performs just as well as MRI 1.8.7 (with about double the memory usage). I was expecting the interpreter startup time to hold Jruby back, but that didn’t turn out to be the case. Rubinius also performed a bit better than expected (they’ve been working on correctness rather than speed thus far). It wasn’t much slower than MRI 1.8.6, although it consumed far more RAM. My understanding is that the VM is currently being rewritten, so I’ll run a few more tests when it’s released.
MacRuby is also an interesting project, with a goal of porting MRI 1.9 to run directly on top of Mac OS X core technologies such as the Objective-C common runtime and garbage collector, and the CoreFoundation framework. It’s very much a work in progress at this point.
Microsoft Doesn't Care About the Web
August 6th, 2008
Microsoft FAIL.
acts_as_paranoid and counter_cache
July 27th, 2008
Counter caches in RoR eliminate the need to issue an sql query to determine the size of an associated collection. Using counter cache is quite simple. Here’s an example:
class Author < ActiveRecord::Base
has_many :books
end
class Book < ActiveRecord::Base
belongs_to :author, :counter_cache => true
end
add_column :authors, :books_count, :integer
Author.first.books.count # gets the value from the books_count column,
# rather than doing an sql count
There’s a problem if you use this alongside acts_as_paranoid. AAP is a plugin that provides ‘soft delete’ functionality. In order to achieve this, AAP overrides AR finder methods to check the ‘deleted_at’ column to determine if a record has been ‘deleted’. Due to a condition placed on the count (counting only undeleted objects), the counter cache is not used and instead an sql statement is issued.
class Author < ActiveRecord::Base
has_many :books
end
class Book < ActiveRecord::Base
acts_as_paranoid
belongs_to :author, :counter_cache => true
end
Author.first.books.count # SELECT count(*) AS count_all FROM `books`
# WHERE (`books`.author_id = 11524) AND
# (`books`.deleted_at IS NULL OR
# `books`.deleted_at > '2008-07-27 13:27:22')
Deleting an object from a ‘paranoid’ collection will still do the right thing (decrement the counter cache), making this easy to fix. You just have to add your own count method for the collection.
class Author < ActiveRecord::Base
has_many :books do
def count
books_count
end
end
end
Author.first.books.count # calls the count method, returning
# the books counter
This is also published on Learnhub
Nginx + HaProxy gotcha
July 22nd, 2008
I’ve recently switched from using a straight up Apache mod_proxy + mongrel setup to Nginx + HaProxy +mongrel. Basically, mod_proxy is dumb as shit, and should never be used with mongrel + rails, especially with better options like Passenger and HaProxy.
Why does mod_proxy suck? Take a look for yourself:
[8030/5/247]: handling 127.0.0.1: GET
[8031/6/134]: handling 127.0.0.1: GET
[8032/2/160]: handling 127.0.0.1: GET
[8033/0/93]: idle
[8034/10/128]: handling 127.0.0.1: GET
[8036/2/124]: handling 127.0.0.1: GET
[8035/0/110]: idle
[8037/0/101]: idle
Look at this garbage. There are three idle mongrels even though the other five have 25 requests to be processed.
Whats great about HaProxy is that it will queue up requests and only distribute them to idle mongrels. It translates into way better response times under load. Add Nginx, which is way easier to configure that Apache, allowing me to easily setup things like sending known ‘slow’ requests to separate mongrels and it’s a big win. As a bonus, haproxy has a great status tool, which gives a quick overview of your proxy clusters.
One little problem …
The gotcha when I initially switched over was that exception_notifier stopped sending me error emails, in fact the errors were being displayed to the user. What the hell?Exception notifier looks at the incoming IP address. If it’s local (aka: 127.0.0.1), it’s assumed that the user is a developer, so it won’t email the exception to you. haproxy was sending nginx’s IP address, rather than the forwarded client address. The problem was that I had configured both nginx and haproxy to forward headers.
haproxy.conf:
option forwardfor # enable insert of X-Forwarded-For headers
nginx.conf
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Removing the header forwarding in the haproxy configuration solved the problem. You only need to set the X-Forwarded header in Nginx (or Apache or Pound or whatever front end you choose). Setting it in Haproxy as well will over write the header with one containing the IP of the front end. Since I have Nginx and Haproxy running on the same machine, that IP is 127.0.0.1, which broke the exception_notifier.
This is also published on Learnhub
Ruby Fringe
July 21st, 2008
Ruby Fringe wrapped up today and it was incredible. All of the presentations were compelling, the food was great and the parties were tons of fun. I met a ton of interesting people (who are way smarter than me), and find myself exhausted and happy.
Congratulations goes out to Pete, Meghann and the rest of the Unspace for pulling together such a great event.
Upgrading non-trivial apps to Rails 2.1
June 25th, 2008
I finished updating Learnhub to run on Rails 2.1. I wrote an article about a few things I learned along the way: Upgrading non-trivial apps to Rails 2.1
Microsoft Office Protocol Discovery is annoying
June 12th, 2008
If you’re getting annoying exception notifications, generated by a client named “Microsoft Office Protocol Discovery”, or even “Microsoft Data Access Internet Publishing Provider Protocol Discovery” this will help.
Fun with Learnhub
June 11th, 2008
We finally have launched the new Learnhub homepage after spending a lot of effort on it. It looks great!
Also, TechCrunch posted a positive article on Learnhub Check it out!
Railsconf 08 on video
June 3rd, 2008
There were some great interviews recorded at Railsconf, and Rails Envy release some new videos. Here they are:
Session Store Switching
May 21st, 2008
I wrote a short article about a little gotcha, and the solution to it when switching your rails session store. Check it out: http://rails.learnhub.com/lesson/page/1858-how-to-switch-your-default-session-store
How to convert your svn repo to git
April 3rd, 2008
Everyone loves git (unless you love mecurial), and svn is so passe, so it’s time to hop on the bandwagon!
Step 1: Install Git. I use macports.
# sudo port install git-core +svn
Others may want to use one of these commands:
# sudo apt-get install git-core
# yum install git-core
# emerge -av git
# sudo pkg_add -i git-svn
# sudo pkg_add -r git
Step 2: Check out your svn project with git. This may take a while, my project took about 20 minutes and it has 1300+ commits.
# git-svn clone https://svn.yourhost.name/projectname projectname.git
Step 3: Get any commits that may have been made to your subversion repo while you were exporting it.
# git-svn rebase
Now you’ve got a functional git clone of your subversion repo. git commands are very similar to svn commands. For example:
# git commit -a -m "This is a commit message"
# git help (to learn about more commands)
If you want to commit the changes you have made to your git repo to your svn repo, it’s quite easy:
# git-svn dcommit
This article is also published on Learnhub
Calling partials through helpers
April 3rd, 2008
Rails partials are are fragments of template code that can be inserted into a view. They can really simplify template code, by factoring out repeated code.
For example, I often put forms into a partial so that the form can be shared be create and edit views:
= error_messages_for :quiz
- form_for :quiz, @quiz, :url => quizzes_path, :html => {:method => :post} do |form|
= render :partial => 'quizzes/form', :locals => {:form => form}
= submit_tag 'Create'
= error_messages_for :quiz
- form_for :quiz, @quiz, :url => quiz_path(@quiz), :html => {:method => :put} do |form|
= render :partial => 'quizzes/form', :locals => {:form => form}
= submit_tag 'Update'
Many (most) people put the render call directly in their templates. This is not a good idea! What if you want to change the template path, or conditionally render a different template in certain conditions? Now you've got to repeat yourself in both templates, and that's bad news.
A simple way to fix this is to *always* use a helper to render the partial. That way any changes can be made in one place, and it also a great place to store any messy conditional logic so that it doesn't clutter up your templates.
= error_messages_for :quiz
- form_for :quiz, @quiz, :url => quizzes_path, :html => {:method => :post} do |form|
= quiz_form(form)
= submit_tag 'Create'
= error_messages_for :quiz
- form_for :quiz, @quiz, :url => quiz_path(@quiz), :html => {:method => :put} do |form|
= quiz_form(form)
= submit_tag 'Update
def quiz_form(form)
render :partial => 'quizzes/form', :locals => {:form => form}
end
Now if I want to do something, like say render a different form depending on a user's preference, it's easy to do.
= error_messages_for :quiz
- form_for :quiz, @quiz, :url => quizzes_path, :html => {:method => :post} do |form|
= quiz_form(form, current_user)
= submit_tag 'Create'
def quiz_form(form, user = nil)
if(!user.nil? && user.wants_advanced_quizzes))
render :partial => 'quizzes/advanced_form', :locals => {:form => form}
else
render :partial => 'quizzes/form', :locals => {:form => form}
end
end
IE8 beta is out
March 5th, 2008
A lot of people were really optimistic when it was announced that IE 8 would render Acid2, something that Firefox2 can't even do (Firefox beta3 can however).
It was thought that Microsoft was finally catching up in terms of standards compliance with the other popular browsers. To bad that rendering Acid2 doesn't really mean that the browser is 'standards compliant'. It just means that it can render the subset of the standard that Acid2 tests. With the release of Acid3, it looks like Microsoft focused solely on rendering Acid2, not on the standards in general. IE8 scored a poor 17/100 on Acid3.
On the opposite end of the spectrum, Apple's latest Webkit beta scored 86/100.
Learnhub launches!
March 4th, 2008
A gotcha
February 27th, 2008
Just got bitten by this. Observers are not called when deleting an object via a through collection.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
class Newsletter < ActiveRecord::Base has_many :subscribers has_many :users, :through => :subscribers end class SubscriberObserver < ActiveRecord::Observer def after_destroy(subscriber) # do somethng end end # case 1 # deletes a subscriber object. after_destroy is not called @newsletter.users.delete(user) # case 2 # after_destroy is called. subscriber = @newsletter.subscribers.find(:first, :conditions => ["user_id = ?", user.id]) subscriber.destroy unless subscriber.nil? |
In both cases a subscriber object is being destroyed, but the observer is being called only in the second scenario. I'll have to look into patching this when I get a chance ....
One thing I hate about Rails ...
February 26th, 2008
One thing I truly hate in Rails is ActionMailer. It sucks.
First off (admittedly a minor point), mailers are stored in app/models, even though they are basically a pseudo controllers, complete with view templates (stored in app/views). It makes no sense.
Secondly, ActionMailer does not have access to named routes or any view helpers. The 'rails way' would be to call the mailer from a controller, passing the URL as an argument which is just stupid in my opinion. Most of the time I send an email in an application it is due to a change in an model's state, not due to a specific controller interaction. A nice way of doing this through use of active record observers (which also don't have access to routes).
This means I generally end up hardcoding the URLs in the mailer. It wouldn't be a huge deal if my test coverage checks that the hardcoded url in the email body matches a generated one. But to do that you'll need to write integration tests rather than the default 'ActionMailer' tests that are auto generated. The whole mess frustrates me unlike anything else in Rails.
Merb seems to get it right with its Merb::MailController. Perhaps something similar could be added to Rails via a plugin?
Immutable Attribute Plugin
November 14th, 2007
Updates and such ...
November 3rd, 2007
Last week Carsten and I were able to knock off a beta of Languify, which is a tool to help software developers to collect and manage language translations for software localization. It's pretty simple for now, but we've got a lot of cool ideas that we'll be implementing in the near future. Keep an eye on it!
Facebook Developer Garage Updates
August 11th, 2007
- CityTV did a segment about the event
- Craig Saila posted his slides about profile updates and about FLQ
- Global Nerdy's notes
Rails on OpenBSD
August 10th, 2007
- Install your favorite database server. My favorite is Postgres.
$ sudo pkg_add -i postgresql-server
- Install the ruby database bindings for your favorite database server.
$ sudo pkg_add -i ruby-postgres
- Install rails.
$ sudo pkg_add -i ruby-rails
haml & sass
August 9th, 2007
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="content-type" content="text/html;charset=UTF-8" /> <title><%= controller.action_name %></title> <%= stylesheet_link_tag 'mycss' %> </head> <body> <p style="color: green"> <%= flash[:notice] %> </p> <div id="header"> <h1>Header</h1> </div> <div id="content"> <%= yield %> </div> </body> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
!!!
%html{:xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => "en", :lang => "en"}
%head
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
%title= controller.action_name
= stylesheet_link_tag 'mycss'
%body
%p{:style => "color:green"}= flash[:notice]
#header
%h1 Header
#content
= yield
|
- the information density is greater, so more of the template is visible on screen.
- less characters to type, so less chance to make a typo
- nesting is clearly visible, and no more issues with missing end tags.
Facebook Garage - Part 6
August 7th, 2007
Demo: Carpool by: Rajat Suri
Rajat explains how he produced the idea of Carpool, and how Facebook was the perfect (only?) platform to build it. Facebook already has the users, and it connects people that already trust each other (at least on some level).The app is pretty cool, it shows rides offered and needed, how many miles the user has travelled, and how many CO2 emissions have been avoided by carpooling. Rajat should talk to Zero Footprint about this :)
Demo: My Aquarium by Greg Thomson
This developer's applications have a total of 2.6 million users and 75,000 new users per day. (wow!)
Greg talked about profile updates, which apparently have a failure rate of 5%. He solved the problem by having a queue that runs all of the time, attempting requests until they succeed.
Facebook Garage - Part 5
August 7th, 2007
Updating the Facebook Profile. by Colin Smillie
- content rules
- no iframes, or auto-running flash
- display rules
- consistent presentation and user experience
- The profile page is cached, so your app must notify facebook in order to update the profile page.
- See the fb:ref method for updates.
- multiple handles are possible, so you could update many profiles at once (think of a horrorscope application, only 12 updates would need to be made for many users
Application Demo: "My Free Stuff", by: Ricardo Covo
Ricardo presents his application which was developed with MS tools (dotNet + SQL Server). He also uses iframes, which seems to be less common. Like Rails, dotNet has an API wrapper (several) for ease of use.
Ricardo found the facebook platform to be extremely easy to develop for, and the api wrappers provide seamless integration into your own platform of choice.
Facebook Garage - Part 4
August 7th, 2007
FQL: Overview by Craig Saila
Facebook API calls are just embedded FQL calls.
- common syntac for all methods
- condense facebook queries
- reduce response size
Ex: SELECT current_location FROM user WHERE uid = 324324. This will return an XML response.
There are about two dozen tables that can be queried. The users table is most often queried.
FQL contains some helper functions that help with queries. It's quite PHP like.
You can only query against "indexable" columns in your where statement. You need at least one in your query.
FQL is designed to be efficient, so no JOIN, ORDER BY, GROUP BY or LIMIT. Each FROM can only reference one table. You must also specify each field that you want the query to return ("SELECT *" is not allowed). Sorting of data, etc must be done on the application level.
- Use the developers tools (fql.query)
- Read the API docs
- Share what you learn on your blog or wiki
Facebook Garage - Part 3
August 7th, 2007
FBML (Facebook Markup Language) introduction by Sunil Boodram
FBML is used to tap into Fackbook elements to ease application creation. It's somewhat similar to HTML. Ex: <fb:gogle-analytics> will generate the proper html to add Google Analytics tracking into your app.
Many of the HTML tags work in FBML. Notable exceptions include <script> and <style>. You may use css in your app, but it will be altered in order for it to not break the look of facebook itself.
Facebook provides an FBML test console, which saves repeated uploads to your dev server when building an application.
Check the FBML documentation for existing tags, they make life much easier!
Facebook Developer Garage - Part 2
August 7th, 2007
Jay Goldman explains the anatomy of a facebook application.
- make it look pretty!
- use good keywords, be descriptive
- This page can be really used to sell users on the app. Make it convincing!
- The icon and name are important so that the user remembers what it looks like so they can find it
- Where your application's app is displayed
- Put compelling content on the canvas page, ex: information from your friends
- should contains the user's data, rather than the data from their friends
- consider what will happen if the user turns any of them off
- profile action links
- news feed
- message attachments .. you can attach pretty much anything!
- requests: you can only invite ten friends per day
Facebook Developer Garage - Part 1
August 7th, 2007
- Facebook has 15 billion page views/month
- 2400+ applications, 100 million downloads
- This is the 1st facebook dev garage in Canada to encourage more developers to write apps on facebook
Highlights from the first presentation:
Facebook platfom- Canada has 10% of all facebook developers
- Toronto is one of the top ten cities for facebook developers
- 33 million active users!
- 150, 000 new users per day
- 1,700 applications with more than 100 users
-
Facebook social graph
- Identity
- Information
- Social Context
-
Ninja tricks
- More integration points == better
- News feed is still quite important
-
Profile integration
- Feed shows installations and application actions (add a photo, etc)
- Recent Interactions
- Recently Added Content
- Social Relevancy
- Content for expression (not consumption)
- Timestamps are important (when did it happen?)
- Users want to show off
-
Canvas Page Engagement
- Keep the captive audience
- Use social comparisons
- Increase engagement
- Action buttons are good == big buttons that will generate events that go into the feed
-
Lesser used integration points
- Message
- Composer
- Profile actions
- Wall
- Share
-
Mass distribution
- at least 75% users have installed an app
-
Feed the mini-feed
- Primary Actions
- Temporal
- Include friends
- Increase Relvancy
- Utilize Call-to_action buttons
-
Build Apps to promote core business
- Cross-promote
- Interactive Cross-promotion (ex: iLike)
-
New Opportunities
Virtual currency
- incentive based actions
- self promotion
- social promotion
- ex: pet someone else's pet and earn money. excahnge money to give gifts to other user's pet
- so basically give social capital == rewards for interacting with the site
- apps allow ad network to advertise on your app's canvas space
- high cpm's ($20)
-
APIs on top of the API
- ex: post on SuperWall instead of Wall
-
Metrics to think about
- the facebook effect (aka: the slashdot effect)
- provides dramatic traffic growth to external sites
-
Virality metrics
- Installed base
- Outgoing impressions
- Conversions
-
Engagement metrics
- repeat sessions, etc
There are more articles about the presentations listed below:
IE and innerHTML stupidity
August 7th, 2007
1 2 3 4 5 6 7 8 9 10 |
new Ajax.Request(url, {
method: 'post',
onComplete: function(request)
{
$('mydiv').update(request.responseText);
// .... do more stuff, etc
}
});
|
Railsconf 2007
May 21st, 2007
- It was the first tech conference that I've attended
- My first trip to the west coast. Well, to be truthful, my first trip anywhere west of Sarnia! I need to travel more ....
Highlights
- David Heinemeier Hansson's keynote on friday. Rails 2.0 won't be a revolution as much as an evolution, but it's shaping up to be another fantastic release
- Jim Weirich's presentation "Spam I Have Known". Jim is an excellent speaker, and he explained the issues involved in eliminating wiki spam in an entertaining fashion.
- The Open Mic sessions. They were a fair bit shorter than the ones given at Demo Camp (5 minutes rather than 15) which worked quite well. Statisfy.net was cool, if gimicky.
- The Rails Way talk/Q & A with Jamis Buck and Michael Koziarski. They were a real life version of their fantastic blog, The Rails Way, and they also held a Q & A session, with questions posted via IRC. They pointed out the proper way to use 'map' in routing which prompted me to overhaul all my routes utilizing 'map.with_options'.
- "Choose Your Battles and LetIt::REST" by Hampton Catlin and Jeff Hardy. Their idea of making controllers 'resourceful' looks REALLY promising. I can't wait until it's released
- Dave Thomas's closing keynote. He challenged the Rails community to innovate, comparing the way that we deliver web applications now to the mainframes that served applications in the 1970's.
Lowlights
- The presenter for "Rails Security: Theory and Practice" was a no show. Maybe he thought that his former roommate (who was in attendance) was going to try to shake him down for being a deadbeat ex-housemate




