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 1-10 of 461 total  RSS 

Rails 2.1.0 monkey patch to add the recognized or matched rails route to the request

This was based on code I found here from Chris Cruft - http://cho.hapgoods.com/wordpress/?p=151

Enhanced to support rails 2.1.0 and also allows alias method chains for recognize from other plugins still to work.

module ActionController
  class AbstractRequest
    attr_reader :recognized_route
    
    def init_recognized_route_from_path_parameters
      recognized_route = path_parameters.delete(:recognized_route) 
    end
  end

  module Routing
    
    class RouteSet
      def recognize_with_route(request)
        result = recognize_without_route(request)
        request.init_recognized_route_from_path_parameters
        result
      end
      alias_method_chain :recognize, :route

      def write_recognize_optimized_with_route
        tree = segment_tree(routes)
        body = generate_code(tree)
        instance_eval %{
          def recognize_optimized(path, env)
            segments = to_plain_segments(path)
            index = #{body}
            return nil unless index
            while index < routes.size
              result = routes[index].recognize(path, env) and result[:recognized_route] = routes[index] and return result
              index += 1
            end
            nil
          end
        }, __FILE__, __LINE__
      end
      alias_method_chain :write_recognize_optimized, :route

    end
  end
end

Sharing has_many extensions

Sometimes you extend an ActiveRecord association this way:

has_many :things do
  def active
    find :all, :conditions => ['active = ?', true]
  end
end


You can share the same extensions using a lambda:


extensions = lambda {
  def active
    find :all, :conditions => ['active = ?', true]
  end
}

has_many :things, &extensions
has_many :more_things, &extensions


Automatic Expiration of Rails Action Caching

Would love to get some feedback on this...

No doubt, 5 minutes after posting this, someone will tell me of the built-in Rails way of doing this, but alas I could not find it.

Usage looks like this:

class PeopleController < ApplicationController
  caches_action :show, :for => 1.hour, :cache_path => Proc.new { |c| "people/#{c.params[:id]}_for_#{Person.logged_in.id}" }
end


The ":for => 1.hour" part is where the magic happens.

Basically, this bit of code adds a before_filter that checks the last modified time of the cache entry, and expires it if it is older than the specified time period.

module ActionController
  module Caching
    module Fragments
      # expire a cache key only if the block returns true or
      # if the age of the fragment is more than the specified age argument.
      def expire_fragment_by_mtime(key, age=nil, &block)
        block = Proc.new { |m| m < age.ago } unless block_given?
        if (m = cache_store.mtime(fragment_cache_key(key))) and block.call(m)
          expire_fragment(key)
        end
      end
    end
    module Actions
      module ClassMethods
        # adds an option :for
        # caches_action :show, :for => 2.hours, :cache_path => ...
        # :cache_path is required, unfortunately
        def caches_action_with_for(*actions)
          original_actions = actions.clone
          options = actions.extract_options!
          if for_time = options.delete(:for)
            cache_path = options[:cache_path]
            before_filter do |controller|
              cache_path = cache_path.call(controller) if cache_path.respond_to?(:call)
              controller.expire_fragment_by_mtime(cache_path, for_time)
            end
          end
          caches_action_without_for(*original_actions)
        end
        alias_method_chain :caches_action, :for
      end
    end
  end
end

# Add a method to grab the last modified time of the cache key.
# If you use a store other than the FileStore, you'll need to add
# a method like this to your store.
module ActiveSupport
  module Cache
    class FileStore
      def mtime(name)
        File.mtime(real_file_path(name)) rescue nil
      end
    end
  end
end

Radiant freeze gems

rake radiant:freeze:gems

Rails ajax star rater

Here's some Rails code I created to try out the CSS Star Rating Redux from Komodo Media.

I set up my routes.rb to use REST.

map.resources :titles, :member => { :rate => :any }


I use the Ruby Linguistics Framework to make this implementation easier. Install it using RubyGems (sudo gem install linguistics). And then put the following code at the top of your application_helper.rb file.

require 'linguistics'
Linguistics::use(:en)  # extends Array, String, and Numeric


This code goes in the page you want the rater to appear in, in this example, show.html.erb.

<ul class="star-rating" id="<%= dom_id(@title) -%>_rating"><%= render :partial => '/partials/star_rating', :locals => { :record => @title } %></ul>


Create a partial called _star_rating.html.erb in your RAILS_ROOT/views/partials directory.

<li class="current-rating" style="width: <%= number_to_percentage((record.rating.to_f * 25) / (5 * 25) * 100) -%>;">Currently <%= record.rating -%>/5 Stars.</li>
<% (1..5).each do |i| -%>
    <li><%= link_to_remote pluralize(i, 'Star'), {
        :update => "#{dom_id(record)}_rating",
        :url => eval("rate_#{record.class.name.downcase}_url(:rating => #{i})")
    }, {
        :class => "#{i.en.numwords}-#{i.abs == 1 ? 'star' : 'stars'}",
        :title => "#{pluralize(i, 'star')} out of 5"
    } -%></li>
<% end -%>

app/models/user.rb

require 'digest/sha1'

# this model expects a certain database layout and its based on the name/login pattern.
class User < ActiveRecord::Base
        has_and_belongs_to_many :groups,
                :class_name => 'Group',
                :join_table => 'users_groups'

        def self.authenticate(username, password)
                @user = find(:first, :conditions => ["username = ? AND password = ? and confirmed = ?", username, sha1(password), true])
        end

        def remember_me
                self.remember_token_expires = 2.weeks.from_now
                self.remember_token = Digest::SHA1.hexdigest("GFDHDFUHFJI&&%ET%&*%^£FESER^&J&IJR%TXEYFGU(*I$R^%E&DU&-#{self.email}#{self.remember_token_expires}")
                self.save_with_validation(false)
        end

        def forget_me
                self.remember_token_expires = nil
                self.remember_token = nil
                self.save_with_validation(false)
        end

        def reset_password
                tmppwd = self.generate_password
                write_attribute("password", self.class.sha1(tmppwd))
                self.save_with_validation(false)
                tmppwd
        end

        protected

        def generate_password
                chars = ("a".."z").to_a + ("1".."9").to_a
                Array.new(6, '').collect{chars[rand(chars.size)]}.join
        end

        def self.sha1(pass)
                Digest::SHA1.hexdigest(pass + "FSDT%^Y&JTFHY^&*IFY^H&&*(T&&RG%U&*I^HFGCDUI*TUF^HYU&*Y&T^F&*^&FUH")
        end

        before_create :crypt_password

        def crypt_password
                write_attribute("password", self.class.sha1(password))
        end

        validates_length_of :username, :within => 4..24
        validates_length_of :password, :within => 6..32
        validates_presence_of :username, :password, :password_confirmation
        validates_uniqueness_of :username, :on => :create
        validates_confirmation_of :password, :on => :create

        validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
        validates_format_of :username, :with => /^(\w*)$/i
        validates_format_of :name, :with => /^([\w ]*)$/i

        validates_presence_of :email, :name
        validates_length_of :name, :within => 6..32
        validates_uniqueness_of :email, :on => :create
end

rails-commit: Rails Commit Script for Subversion

#!/usr/bin/env ruby

# my take on a easy commit script for rails...
# it is far from prefect, so:
# please feed back the modifications you made to it!
#
# Fixed bugs on empty to_ arrays and spelling mistakes
# by Vesa-Pekka Palmu
# orginal by Cies Breijs -- cies.breijsATgmailDOTcom
# based on a bash script by Anonymous Gentleman
# found here: http://wiki.rubyonrails.org/rails/pages/HowtoUseRailsWithSubversion
# cleaned up an pasted by Ed Laczynski http://idisposable.net

to_add = []
to_remove = []
to_checkin = []

`svn status`.each_line do |l|
puts l
action_char, path = l.split(' ', 2)
path.strip!
case action_char
when '?'
to_add << path
when '!'
to_remove << path
when 'M'
to_checkin << path
end
end

puts "\nyou are about to"

def print_list(array, str)
puts "\n#{str}:"
array.each { |i| puts "\t"+i }
puts "\t<nothing>" if array.length == 0
end

print_list(to_add, 'add')
print_list(to_remove, 'remove')
print_list(to_checkin, 'checkin')

puts "\nplease write something for the commit log and hit enter"
puts "(hitting enter on an empty line will cancel this commit)\n\n"

log = gets.strip

if log.empty?
puts "commit cancelled!\n"
exit
end

puts "\ncontacting repository\n"

`svn add #{to_add.join(' ')}` unless to_add.empty?
`svn remove #{to_remove.join(' ')}` unless to_remove.empty?
puts "\n" + `svn commit -m "#{log.gsub('"', '"')}"` + "\n"

puts "running \'svn update\' to be sure we are up-to-date"
puts `svn update`

puts "\nfinished.\n"

String Translit for Rails

// Translit for Rails using ActiveSupport. (convert é in e and other utf8 codes in latin chars)

class String
  def translit
    ActiveSupport::Multibyte::Handlers::UTF8Handler.normalize(self,:d).split(//u).reject { |e| e.length > 1 }.join
  end
end

Rails label helper for forms

When creating forms I get tired of creating labels for each field so I like to shorten my typing by using this application helper.

def l(id,label)
    "<label for='#{id}'>#{label}</label>"
end


then later on in your view you type
<%= l('my_field_id','My Label') %>

Fix NumberHelper to account for negative numbers

module ActionView
  module Helpers
    module NumberHelper
      def number_to_currency(number, options = {})
        options  = options.stringify_keys
        precision = options["precision"] || 2
        unit    = options["unit"] || "$"
        separator = precision > 0 ? options["separator"] || "." : ""
        delimiter = options["delimiter"] || ","

        begin
          parts = number_with_precision(number, precision).split('.')
          delimitered_number = number_with_delimiter(parts[0], delimiter) + separator + parts[1].to_s
          if Float(number) >= 0.00
            unit + delimitered_number
          else
            #'(' + unit + delimitered_number.gsub(/^-/, '') + ')'
            '-' + unit + delimitered_number.gsub(/^-/, '')
          end
        rescue
          number
        end
      end
    end
  end
end
« Newer Snippets
Older Snippets »
Showing 1-10 of 461 total  RSS