Customization

Unless you’re running the imaginary Cascadia Bike Racing Association, you’ll want to change some things about your Racing on Rails site. There are two ways to do that: pages and local.

Pages

Racing on Rails has a simple CMS at /admin/pages. You can add pages and they’ll be automatically accessible. The pages use ERB, the same as Rails templates, and have full access to Rails helpers and ActiveRecord. Pages are a “sharp tool.” Be sure that you trust your admin users.

A page’s path is automatically derived from its title. For example, if you create a New Riders page, its path will be /new_riders. If you create a Race Day page as a child of New Riders, its path will be /new_riders/race_day. You can override this by editing the page’s slug.

If the page path exactly matches /home, /home/recent_results, or /events/upcoming, that page will be used in place of the Racing on Rails template file. This magic only works for controllers and pages that use the render_page helper method. See the ApplicationController and PageHelper classes for details.

You can also use render_page to include a page in another page or Rails template.

That’s a quick overview. Please email me at scott@rocketsurgeryllc.com if you’d like more info.

Local

You’ll almost certainly need to customize more than a few pages. To do so, add a directory named “local” in RAILS_ROOT.

In many situations, Racing on Rails looks for files in RAILS_ROOT/local before falling-back on RAILS_ROOT: * app/views * config/database.yml * config/deploy.rb * config/environment.rb * config/environments/.rb * public

This allows you to override the way pages look, your database credentials, Capistrano deployment recipes, Rails environment, images, stylesheets and JavaScript.

In addition, you can configure RacingAssociation in local/config/environment.rb. Here’s an example from OBRA:

	ASSOCIATION = RacingAssociation.new
	ASSOCIATION.name = 'Oregon Bicycle Racing Association'
	ASSOCIATION.short_name = 'OBRA'
	ASSOCIATION.state = 'OR'
	ASSOCIATION.masters_age = 30
	ASSOCIATION.rental_numbers = 0..99
	ASSOCIATION.show_events_velodrome = false
	ASSOCIATION.show_only_association_sanctioned_races_on_calendar = true
	ASSOCIATION.always_insert_table_headers = true
	ASSOCIATION.competitions = Set.new([:age_graded_bar, :bar, :cat4_womens_race_series, :cross_crusade_series_standings, :ironman, :oregon_cup, :overall_bar, :tabor_series_standings, :team_bar])
	ASSOCIATION.award_cat4_participation_points = false
	ASSOCIATION.cat4_womens_race_series_points = [ 0, 100, 70, 50, 40, 36, 32, 28, 24, 20, 16 ]
	ASSOCIATION.cat4_womens_race_series_category = "Category 4 Women"

	SANCTIONING_ORGANIZATIONS = ["ATRA", "FIAC", "OBRA", "UCI", "USA Cycling"] unless defined?(SANCTIONING_ORGANIZATIONS)
	STATIC_HOST = 'www.obra.org' unless defined?(STATIC_HOST)

	ExceptionNotifier.exception_recipients = %w(scott@butlerpress.com)

In the Future

The local directory works fairly well, and was a good solution for its time (long, long ago: 2006). Rails, plugins, engines, and gems have all improved since then, so there’s probably a better way now.

I may consider per-site engines or gem/gem plugins. I am thinking, though, that I will move everything to the database: RacingAssociation into its own table and all the public pages to database “pages.” The admin pages would be customized by options in RacingAssociation.

Database-driven customization would allow us to run multiple racing associations (sites) in the same database and deployment. That would simplify deployment greatly. However, all code would need to be scoped by RacingAssociation.

The pages feature also opens up a gaping security hole if multiple sites share a database: any admin user can run Rails code from a view, and do things like: User.delete_all or Racer.find(:all). I suspect that I’ll end up rewriting the Comatose CMS plugin. Good thing? Bad thing? Time will tell.