Never been to DZone Snippets 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

« Newer Snippets
Older Snippets »
Showing 11-20 of 111 total

Load select box with model

This will generate a select box loaded with parent model

select :parent_id, Parent.find(:all).collect{|p| [p.full_name, p.id]}, {:include_blank => true}

Custom headers in Rails tests

From time to time you may need to set headers in your functional tests that aren't supported by the @request object. I had to set up my request with Basic authentication.

Add an extension to the TestRequest class in the test/test_helper.rb file:

class ActionController::TestRequest 
  def set_header(name, value)
    @env[name] = value
  end
end


Then set values as required in your functional test.

def test_index
  @request.set_header "HTTP_AUTHORIZATION", "Basic " + Base64.encode64('testuser:testpass')
  get :index
  assert_response :success
  assert_template "index"
end

Linking to the Current Action

This small snippet shows how to link to the current action. Although it's very easy to do, it doesn't seem to be documented anywhere. This comes in handy when your dealing with partials that are called in multiple actions and controllers.
<%= link_to "Insert Link Text", :action => controller.action_name %>

.htaccess That Fixes The Trailing Slash Error

// This .htaccess file is for use with a Rails application that is accessed by a symbolic link. This fixes an error in which the directory URL must have a trailing slash. Otherwise, the user receives a 400 Bad Request error.

Options +FollowSymLinks +ExecCGI

RewriteEngine On

RewriteCond %{SCRIPT_FILENAME}    -d
RewriteCond %{SCRIPT_FILENAME}      ^.*[^\/]$
RewriteRule ^(.*)$ $1/ [N]

#Put the directory your Rails app is in here.
RewriteBase /directory

RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ dispatch.cgi?$1 [QSA,L]

Rails task to find code typos in rhtml templates


namespace :typos do 
  task :rhtml do
    require 'erb'
    require 'active_support'
    require 'action_view'

    module TempTemplates; end
    Dir["./app/views/**/*.rhtml"].each do |fname|
      local_source = ERB.new(IO.read(fname), nil, '-').src
      template_source = "def _tmpl\n#{local_source}\nend"
      begin
        TempTemplates.module_eval(template_source, fname, 0 )
      rescue Object => e
        t = ActionView::TemplateError.new("./app/views/", fname, {}, template_source, e)
        puts "TemplateError (#{t.message}) on line ##{t.line_number} of #{t.file_name}:\n"+t.source_extract + "\n------\n"
      end
    end
  end
end

Synchronizing Rails DB Contents via Fixtures

The following rake task will dump the contents of the current environment's database to YAML fixtures. Stick the following in lib/tasks/fixtures.rake:

namespace :db do
  namespace :fixtures do
    
    desc 'Create YAML test fixtures from data in an existing database.  
    Defaults to development database.  Set RAILS_ENV to override.'
    task :dump => :environment do
      sql  = "SELECT * FROM %s"
      skip_tables = ["schema_info"]
      ActiveRecord::Base.establish_connection(:development)
      (ActiveRecord::Base.connection.tables - skip_tables).each do |table_name|
        i = "000"
        File.open("#{RAILS_ROOT}/test/fixtures/#{table_name}.yml", 'w') do |file|
          data = ActiveRecord::Base.connection.select_all(sql % table_name)
          file.write data.inject({}) { |hash, record|
            hash["#{table_name}_#{i.succ!}"] = record
            hash
          }.to_yaml
        end
      end
    end
  end
end


After making changes to the database that you'd like to dump to fixtures:

rake db:fixtures:dump


After checking out updated fixtures from SVN:

rake db:migrate
rake db:fixtures:load

Request Database Authentication When Rails Boots

Simple solution to a problem that may not affect very many folks.
If you don't like your password displayed in plain text in database.yml, this might help you.
It utilizes the Highline gem (big thanks to James Edward Gray II).

# database.yml

<%
require 'highline/import'

def request_input(msg, show_input = true)
  ask(msg) { |q| q.echo = show_input }
end
%>

#...
  username: <%= request_input 'Username: ' %>
  password: <%= request_input 'Password: ', false %>
#...

HTML (TWiki Calendar) to iCal Proxy

Run the Ruby on Rails code below in a webserver (like Lighthttp) and you can subscribe your TWiki Calendar with iCal or Mozilla Sunbird.

It is also a nice example to show, how good and easy the icalendar (create and read icalendars) and the hpricot (html parser) libraries (gems) are.

require 'rubygems'
require 'hpricot'
require 'open-uri'
require 'icalendar'
require 'date'

class IcalController < ApplicationController
	include Icalendar
	def index
		doc = Hpricot(open("http://irgendwo.net/twiki/bin/view/Main/TermineProjekte"))

		cal = Calendar.new
	
		(doc/"#kalender/table").each do |table|
			(table/"/tr").each do |row|
	
				inner_table = (row/"/td/table").first
	
				first_row = true 
				monat = nil
				monat_jahr = Array.new
	
				(inner_table/"/tr").each do | inner_row |
					if first_row
						monat = "#{(inner_row/"/td/center/font").inner_html}"
						monat_jahr = monat.split
						first_row = false
					else
	
						(inner_row/"td").each do |cell|
							text = cell.inner_html
							text = text.gsub(/<(br )\/?>/," / ")
							text = text.gsub( /<\/?[^>]+(>|$)/, "" ) 
							
							unless text == "&nbsp;" or text.size <= 2
								event = Event.new
								event.start = Date.new(monat_jahr[1].to_i, Date::MONTHNAMES.index(monat_jahr[0]), text[0..1].to_i)
								event.summary = "#{text[5..text.size]}"
								cal.add_event(event)
							end
						end
					end
				end
			end  
		end
		cal_string = cal.to_ical
		send_data cal_string, :filename => "it_calendar.ics", :type => "text/calendar"
	end
end

Numeric colums for latitude / longitude in Rails 1.2 migrations

In Rails 1.1.6, "numeric" datatypes didn't work in migrations. This confused a lot of people who wanted to store geographic data (latitude and longitude) for use in Google Maps and the like. Floats worked, but their precision is limited -- you'll lose three or more decimal places of precision if you store the results of a typical geocoding call in a Float column. And don't even think about using strings to store your latitudes/longitudes.

Fortunately, the numeric datatype problem is fixed in Rails 1.2, and you can now have do this in your migrations:

class CreatePlaces < ActiveRecord::Migration
  def self.up
    create_table :places do |t|
      t.column "lat", :decimal, :precision => 15, :scale => 10
      t.column "lng", :decimal, :precision => 15, :scale => 10
    end
  end

  def self.down
    drop_table :places
  end
end


FYI, if you're stuck on Rails 1.1.6, you can use this approach:
class CreatePlaces < ActiveRecord::Migration
  def self.up
    create_table :places do |t|
      t.column :lat, :float 
      t.column :lng, :float
    end
    execute("ALTER TABLE places MODIFY lat numeric(15,10);")
    execute("ALTER TABLE places MODIFY lng numeric(15,10);")
  end

  def self.down
    drop_table :places
  end
end

... but that's ugly, database-specific (works on MySQL), and not very DRY.

RJS with toggle_slide if not visible only

RJS is very powerful. here is a small code snippet that shows how to do a toggle on a div if NOT visible. If the div is visible, it just exchange it. Here is my rhtml code:

    <div style="height: 30px">
        <div style="float: left; padding: 0 0 0 180px">
            <%= link_to_remote("test_visibility" , 
                :with => "'is_visible=' + Element.visible('list_div')",
                :loading => "Element.show('getting_results')",
                :complete => "Element.hide('getting_results')",
                :failure => "alert('An error occured, please email us directly!')",
                :url => { :action => 'one_action' }) %>
        </div>
        <div id="getting_results" style="float: left; padding: 3px 0 0 30px; display: none;">
            <%= image_tag "ajax-loader.gif", :class => "image", :alt => "loading..." %>
        </div>
    </div>
    
    <div id="list_div" style="display: none;" >
    </div>
    


And in my controller, I have the following code:

def one_action
      render :update do | page |
        page.replace_html 'list_div', :partial => 'one_partial'
        if params['is_visible'] == 'false'
          page.visual_effect :toggle_slide, 'list_div', :duration => 2
        end       
      end
end


How it works?
Element.visible('list_div')
is a prototype function that returns false if the element is not visible and true if it is. In the above case, we have the orginial visibility of the div to be "display: none". Thus the first time the action is called, the Ajax call will send the parameter false to the action. This will make the div appear. For subsequent requests, the value of visibility will be true, thus only replacing the div.
« Newer Snippets
Older Snippets »
Showing 11-20 of 111 total