Never been to CodeSnippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world (or not, you can keep them private!)

ruby state options array


STATES = [
    [ "Alabama", "AL" ],
    [ "Alaska", "AK" ],
    [ "Arizona", "AZ" ],
    [ "Arkansas", "AR" ],
    [ "California", "CA" ],
    [ "Colorado", "CO" ],
    [ "Connecticut", "CT" ],
    [ "Delaware", "DE" ],
    [ "Florida", "FL" ],
    [ "Georgia", "GA" ],
    [ "Hawaii", "HI" ],
    [ "Idaho", "ID" ],
    [ "Illinois", "IL" ],
    [ "Indiana", "IN" ],
    [ "Iowa", "IA" ],
    [ "Kansas", "KS" ],
    [ "Kentucky", "KY" ],
    [ "Louisiana", "LA" ],
    [ "Maine", "ME" ],
    [ "Maryland", "MD" ],
    [ "Massachusetts", "MA" ],
    [ "Michigan", "MI" ],
    [ "Minnesota", "MN" ],
    [ "Mississippi", "MS" ],
    [ "Missouri", "MO" ],
    [ "Montana", "MT" ],
    [ "Nebraska", "NE" ],
    [ "Nevada", "NV" ],
    [ "New Hampshire", "NH" ],
    [ "New Jersey", "NJ" ],
    [ "New Mexico", "NM" ],
    [ "New York", "NY" ],
    [ "North Carolina", "NC" ],
    [ "North Dakota", "ND" ],
    [ "Ohio", "OH" ],
    [ "Oklahoma", "OK" ],
    [ "Oregon", "OR" ],
    [ "Pennsylvania", "PA" ],
    [ "Rhode Island", "RI" ],
    [ "South Carolina", "SC" ],
    [ "South Dakota", "SD" ],
    [ "Tennessee", "TN" ],
    [ "Texas", "TX" ],
    [ "Utah", "UT" ],
    [ "Vermont", "VT" ],
    [ "Virginia", "VA" ],
    [ "Washington", "WA" ],
    [ "West Virginia", "WV" ],
    [ "Wisconsin", "WI" ],
    [ "Wyoming", "WY" ]
  ]

<%= form.select :state, STATES, :include_blank => true %>

Friendlier Error Messages in Rails

// Just modify your error_messages_for in your views...

<%= error_messages_for :order, :header_message => "Please Try Again!", :message => "We had some problems saving your information:" %>       

Export to Excel

Controller
class PersonController < ApplicationController
  def export
    headers['Content-Type'] = "application/vnd.ms-excel"
    headers['Content-Disposition'] = 'attachment; filename="report.xls"'
    headers['Cache-Control'] = ''
    @person = People.find(:all)
  end
end


View (link to export)
<%= link_to "Export as Excel", export_person_url %>


View (Export)
#Render partial so your Layout wont be sent to the spreadsheet
<%= render :partial => 'report' %>


Partial
<table border="1">
  <tr>
    <th>Name</th>
  </tr>
  <% @person.each do |p| %>
    <tr>
      <td><%= p.name %></td>
    <% end %>
  </tr>
</table>

HABTM

Migration
class CreateJoinGenresPerformers < ActiveRecord::Migration
  def self.up
    create_table :genres_performers, :id=>false do |t|
      t.references  :genre
      t.references  :performer
    end
    add_index :genres_performers, :genre_id
    add_index :genres_performers, :performer_id
  end

  def self.down
    drop_table :genres_performers
  end
end


Model
class Performer < ActiveRecord::Base
  has_and_belongs_to_many :genres
  #...
end

class Genre < ActiveRecord::Base
  has_and_belongs_to_many :performers
  #...
end


Controller
def edit
  params[:model][:genre_ids] ||= [] if params[:model]
  #...
end


View
<div class="block has-layout habtm">
	<% for g in Genre.find(:all, :order=>"name ASC") %>
	<span>
		<label><%= check_box_tag "model[genre_ids][]", g.id, @model.genres.include?(g), {:id=>nil} %> <%= h g.name %></label>
	</span>
	<% end %>
</div>

Deployment Recipe for Joyent Shared Accelerator

This is the deploy.rb I am using with a Shared Accelerator (with a few changes). It assumes you are using Mongrel and a proxy to serve the application. Joyent has good examples for those in the KB.

Not everything is *required* for a Shared Accelerator, but better to have some placeholders if you move your application later. The standard Capistrano :setup task worked for me, surprisingly. Haven't tried it since 2.0 or so.

The tasks for deploy:web:disable and deploy:web:enable are hacks. Ideas would be appreciated. Using the "pkill mongrel" trick hasn't always worked for me (sometimes SMF doesn't restart it), so I do it manually.

This isn't perfect, but hopefully it helps.

### deploy.rb
  set :application, "my_application"
  set :domain, "humboldt.joyent.us"

  set :user, "my_user"
  set :runner, user
  set :admin_runner, user # Does nothing on a Shared Accelerator
  set :scm_username, user
  set(:scm_password){Capistrano::CLI.password_prompt("Subversion Password: ")}
  
  set :scm, :subversion
  set :repository, "svn+ssh://#{scm_username}@#{domain}/users/home/#{user}/svn/#{application}/trunk/"
  set :checkout, "export"

  role :app, domain
  # These aren't required if you are just using one Shared Accelerator, but it's good practice
  role :web, domain
  role :db, domain, :primary => true
  
  set :deploy_to, "/users/home/#{user}/web/#{application}" # Or wherever you want the application root to be

  set :service_name, "smf-service_name" # Irrelevant because SMF doesn't work from the CLI on shared - left in as a reminder of a dream
  set :mongrel_config, "#{deploy_to}/shared/config/mongrel_cluster.yml" # Similarly irrelevant on Shared
  set :use_sudo, false # Don't need sudo on a shared accelerator
  default_run_options[:pty] = true # Much time was lost figuring this one out - see http://weblog.jamisbuck.org/2007/10/14/capistrano-2-1

# Shared Accelerators don't allow CLI access to SMF on Solaris
# Capistrano will throw warnings/errors if you don't overwrite these methods.
# It's a good opportunity to throw in a reminder about it.
namespace :deploy do
  desc "Restart the service"
  task :restart, :roles => :app  do
    puts "Remember to restart this from Webmin for changes to take effect."
    # Some svcadm stuff would go here if it worked
  end
  
  desc "Start the service" # The :spinner task went out of style when Mongrel and the gang came to town
  task :start, :roles => :app  do
    puts "Remember to start this from Webmin for changes to take effect."
  end
  
  desc "Stop the service"
  task :stop, :roles => :app do
    puts "This service must be stopped from Webmin."
  end
  
  # These tasks are used to enable/disable the application by replacing a .htaccess file
  # Surely someone has a better idea.
  namespace :web do
    desc "Present a maintenance page to visitors."
    task :disable, :roles => :web do
      run "cp /users/home/#{user}/web/public/down.txt /users/home/#{user}/web/public/.htaccess"
    end
    
    desc "Makes the application web-accessible again."
    task :enable, :roles => :web do
      run "cp /users/home/#{user}/web/public/up.txt /users/home/#{user}/web/public/.htaccess"
    end
  end
end

rails preserve line breaks



simple_format(string)

Rails numbered migrations instead of timestamps

change migrations to the old rails way of just version numbers instead of the mysql timestamp. Only recommended if a few people are working on a project.
config.active_record.timestamped_migrations = false

Using rescue_from

Controller
rescue_from ActiveRecord::RecordNotFound, :with=>:record_not_found


def record_not_found
  set_site_settings(:bad_record)
  logger.error("Attempt to access invalid entry")
  flash.now[:app_error] = "Attempt to access invalid entry"
  render :template=>"pages/shared/bad_record"
end


bad_record.html.erb
<% if params[:action].index(/product/) %>
<p>This item has been removed from our database.</p>
<p>Click on any of the links below to continue browsing our website.</p>
<ul class="plainlist">
	<li><%= internal_link_to "Home", :home, "/" %></li>
	<li><%= internal_link_to "Products", :promotional, products_path %></li>
</ul>
<% end %>

Reload rails plugins in console


add to environment.rb
config.reload_plugins = true

Enquiry Form

Controller
def online_enquiry
  set_site_settings(:online_enquiry)
  @mailer = MailerOnlineEnquiry.new(params[:mailer])
  if request.post? and @mailer.save and params[:enquiry_cap].blank?
    begin
      Mailer::deliver_online_enquiry(
        :to=>"#{@setting[:site].site_title} <#{MAILER_RECIPIENTS[:default]}>",
        :subject=>"Website Online Enquiry",
        :mailer=>@mailer
      )
      @mailer = MailerOnlineEnquiry.new
      #complete
      flash[:app_success] = "Your enquiry was successfully delivered"
      redirect_to mailer_complete_path(:mailer_reference=>"online-enquiry")
    rescue
      flash.now[:app_error] = "Oops... Something went wrong"
    end
  end
end


View
<% unless @mailer.errors.empty? %>
<p class="flash app_error"><%= pluralize @mailer.errors.count, "error" %>  prohibited your Enquiry from being submitted</p>
<% end %>
<% form_for :mailer, :url=>request.env["REQUEST_URI"], :html=>{:multipart=>true}, :builder=>NetAgeLabeledFormBuilder do |f| %>
<fieldset>
<div class="block">
	<dl>
        <%= f.text_field :name, :required=>true, :class=>"medium" %>
	</dl>
	<div class="cap-field">
		<%= text_field_tag :enquiry_cap, params[:enquiry_cap] %>
	</div>
	<div class="action">
		<%= content_tag :button, "Submit", {:name=>"commit", :type=>"submit", :class=>"button-submit"} %>
	</div>
</div>
</fieldset>
<% end %>


Models
tableless.rb
class Tableless < ActiveRecord::Base
  def self.columns() @columns ||= []; end

  def self.column(name, sql_type=nil, default=nil, null=true) 
    columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null) 
  end

  def save(validate=true)
    validate ? valid? : true
  end
end


mailer_online_enquiry.rb
class MailerOnlineEnquiry < Tableless
  column :name, :string
  column :contact_number, :string
  column :email_address, :string
  column :comments, :string

  validates_presence_of :name, :contact_number
  validates_format_of :email_address, :with=>/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/
end