« Newer Snippets
Older Snippets »
Showing 41-60 of 70 total

Copy data from database into fixtures

Take from pylonhead.com

  def self.to_fixture
    write_file(File.expand_path("test/fixtures/#{table_name}.yml", RAILS_ROOT),
      self.find(:all).inject("---\n") { |s, record|
        self.columns.inject(s+"#{record.id}:\n") { |s, c|
          s+"  #{{c.name => record.attributes[c.name]}.to_yaml[5..-1]}\n" }
    })
  end

Bulk svn actions (usefull with rails)

Just run this code from inside your repository. This will do a bulk action like "svn add" on each file marked with the given filter (like '?') when doing "svn status"

Beware: this code might break with multi word filenames...

usage :
# ./svn_bulk ? add ---> this shows a preview of the actions
# ./svn_bulk ? add 1 ---> action !
#!/usr/bin/ruby
sign, action, doit = ARGV
sign = '\?' if sign == '?'
list = IO.popen("svn st")
list.each {|i|
if (i =~ /^#{sign}\s*(.*)/) 
cmd = "svn #{action} '"+$1+"'"
print cmd + "\n"
system(cmd) if doit
end
}

Very simple act_as base file

This is a very simple file to show how to add 'act_as_whatever' to ActiveRecord.

To use it, put the code into a file like lib/your_super_name/acts/idiot.rb and voilà.
Thanks to technoweenie for "acts_as_paranoid" which I used with "acts_as_tree" to build this template.

module YourSuperName
  module Acts
    module Idiot
      # this is called when the module is included into the 'base' module
      def self.included(base)
        # add all methods from the module "AddActsAsMethod" to the 'base' module
        base.extend AddActsAsMethod
      end
      module AddActsAsMethod
        def acts_as_idiot
          # BELONGS_TO HAS_MANY GOES HERE

          class_eval <<-END
            include YourSuperName::Acts::Idiot::InstanceMethods
          END
        end
      end
      
      
      module InstanceMethods
        def self.included(aClass)
          aClass.extend ClassMethods
        end

        # PUT YOUR INSTANCE METHODS HERE
        def idiot(msg)
          "#{self}: I am an idiotic object. And I say '#{msg}'."
        end
        
        module ClassMethods
          # PUT YOUR CLASS METHODS HERE
          def idiot(msg)
          "#{self}: I am an idiotic class. And I say '#{msg}'."
          end
        end
      end
    end
  end
end

ActiveRecord::Base.send :include, YourSuperName::Acts::Idiot

Getting a less verbose list of installed gems

Wanna know what gems you have installed without looking at all the descriptions?

gem list | egrep -v "^( |$)"


Here's a (trimmed) sample output:

$ gem list | egrep -v "^ |^$"
*** LOCAL GEMS ***
actionmailer (1.2.1, 1.2.0, 1.1.5)
actionpack (1.12.1, 1.12.0, 1.11.2)
actionwebservice (1.1.2, 1.1.1, 1.1.0, 1.0.0)
activerecord (1.14.2, 1.14.1, 1.14.0, 1.13.2)
activesupport (1.3.1, 1.3.0, 1.2.5)
BlueCloth (1.0.0)
capistrano (1.1.0)
diff-lcs (1.1.2)

Upload your Flickr photos to Strongspace

require 'net/http'
require 'rubygems'
require_gem 'flickr'
require_gem 'net-sftp'

flickr_username = "[email protected]"
flickr_pass = 'x'
strongie_pass = 'x'
strongie_username = 'johan'
strongie_upload_dir = "flickr_test"

flickr = Flickr.new 
flickr.login(flickr_username, flickr_pass)
user = flickr.users(flickr_username)

Net::SFTP.start("#{strongie_username}.strongspace.com", strongie_username, strongie_pass) do |sftp|
  Net::HTTP.start('static.flickr.com') do |http|
    user.photos.each do |photo|
      src_url = photo.source('Large').sub("http://static.flickr.com", '')    
      puts "Fetching \"#{photo.title}\"..."
      res = http.get(src_url)
      filename = File.basename(src_url)
      sftp.open_handle("/home/#{strongie_username}/#{strongie_upload_dir}/#{filename}", 'w') do |handle|
        result = sftp.write(handle, res.body)
        puts "Wrote #{filename} with result code: #{result.code}..."
      end    
    end
  end
end

Format an integer with commas to make it more readable

More information or better ways of doing this welcome ...

def commify(number)
    c = { :value => "", :length => 0 }
    r = number.to_s.reverse.split("").inject(c) do |t, e|  
      iv, il = t[:value], t[:length]
      iv += ',' if il % 3 == 0 && il != 0    
      { :value => iv + e, :length => il + 1 }
    end
    r[:value].reverse!
  end


Alex Young suggested

def commify(v)
 (s=v.to_s;x=s.length;s).rjust(x+(3-(x%3))).scan(/.{3}/).join(',').strip
end


and there's always

number_with_delimiter(number, delimiter)


from NumberHelper in the Rails API ... which is implemented as follows:-

def number_with_delimiter(number, delimiter=",")
  number.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
end


They don't always work too well when the number has a decimal point in it (and more than two or so digits after the decimal point), so there's room for an improved version ...

JV suggested the following snippet from http://pleac.sourceforge.net/pleac_ruby/numbers.html which appears to be able to handle commas and decimal places as well.

def commify(n)
    n.to_s =~ /([^\.]*)(\..*)?/
    int, dec = $1.reverse, $2 ? $2 : ""
    while int.gsub!(/(,|\.|^)(\d{3})(\d)/, '\1\2,\3')
    end
    int.reverse + dec
end

Clearing out ruby sessions less than a day old (meaning that etc periodic won't get)

find /tmp/ -name "ruby_sess*" -cmin +1 -exec rm \{} \;
find /tmp/ -name "*request_body*" -cmin +1 -exec rm \{} \;
find /tmp/ -name "*CGI*" -cmin +1 -exec rm \{} \;
find /tmp/ -name "*apr*" -cmin +1 -exec rm \{} \;
find /tmp/ -name "open-uri*" -cmin +1 -exec rm \{} \;
find /tmp/ -name "vi*" -cmin +1 -exec rm \{} \;
find /tmp/ -name "sess_*" -cmin +1 -exec rm \{} \;
find /var/tmp/ -name "sess_*" -cmin +1 -exec rm \{} \;

Install Rails/lighttpd with DarwinPorts for Tiger

install darwinports package

Add 'export PATH=/opt/local/bin:$PATH' to ~/.bashrc

sudo port -d selfupdate

sudo port install ruby

sudo port install rb-rubygems

sudo gem install rails --include-dependencies

sudo port install readline

sudo port install lighttpd

vi /opt/local/etc/lighttpd.conf [edit lighttpd.conf to your liking]

set up launchd item for lighttpd
        -- restart lighttpd: sudo launchctl stop net.lighttpd
                             sudo launchctl start net.lighttpd

sudo port install fcgi

sudo port install rb-fcgi
         
install official OS X MySQL package (not darwinports)

sudo gem install mysql -- --with-mysql-dir=/usr/local/mysql


Links:
darwinports package
launchd item
OS X MySQL package

Rake task to load fixtures in a specific order

The default task for loading fixtures, rake load_fixtures, appears to load the fixture data in alphabetical order. If you have foreign key or other constraints, it may be impossible to load the fixtures into the database.

The rake task below searches for a file called test/ordered_fixtures.rb and loads that file. The file contains code that sets an environment variable specifying the load order for fixtures.

ENV["FIXTURE_ORDER"] = 
  %w( entities interaction_sources interaction_devices payments 
      interactions accounts employments enrollments payables 
      receivables tenures wards ).join(' ')


The lib/tasks/fixtures.rake (rake load_fixtures_ordered) task first loads all fixtures specified via ordered_fixtures, and then loads all other fixtures not specified as being ordered so it should work for you even if you do not create an ordered_fixtures file.

require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")
require File.expand_path(File.dirname(__FILE__) + "/../../test/ordered_fixtures")

ENV["FIXTURE_ORDER"] ||= ""

desc "Load fixtures into #{ENV['RAILS_ENV']} database"
task :load_fixtures_ordered => :environment do
  require 'active_record/fixtures'  
  ordered_fixtures = Hash.new
  ENV["FIXTURE_ORDER"].split.each { |fx| ordered_fixtures[fx] = nil }
  other_fixtures = Dir.glob(File.join(RAILS_ROOT, 'test', 'fixtures', '*.{yml,csv}')).collect { |file| File.basename(file, '.*') }.reject {|fx| ordered_fixtures.key? fx }
  ActiveRecord::Base.establish_connection(ENV['RAILS_ENV'])
  (ordered_fixtures.keys + other_fixtures).each do |fixture|
    Fixtures.create_fixtures('test/fixtures',  fixture)
  end unless :environment == 'production' 
  # You really don't want to load your *fixtures* 
  # into your production database, do you?  
end


The code may not be the best but it Works For Me.

Rails MySQL Session Sweeper

1) Download the launchd GUI, Lingon, from: http://lingon.sourceforge.net/

2) Add hourly job:

$RAILS_APP_DIR/script/runner 'ActiveRecord::Base.connection.delete("DELETE FROM sessions WHERE updated_at < now() - INTERVAL 1 HOUR")'


3) My launchd task plist file (yours will vary):

<?xml version="1.0" encoding="UTF-8"?>
DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Labelkey>
        us.boygeni.mysql-session-sweeper</string>
        <key>LowPriorityIOkey>
        />
        <key>ProgramArgumentskey>
        
                /users/defeated/Sites/rails_apps/boygenius/script/runnerstring>
                'ActiveRecord::Base.connection.delete("DELETE FROM sessions WHERE updated_at < now() - INTERVAL 1 HOUR")'</string>
        array>
        RunAtLoad</key>
        <true/>
        <key>StartIntervalkey>
        3600</integer>
dict>
</plist>

Is this error in installing rails via rubygems important?

Horatio:~ Rahul$ sudo gem install rails --include-dependencies
Attempting local installation of 'rails'
Local gem file not found: rails*.gem
Attempting remote installation of 'rails'
Updating Gem source index for: http://gems.rubyforge.org
Successfully installed rails-1.0.0
Successfully installed rake-0.6.2
Successfully installed activesupport-1.2.5
Successfully installed activerecord-1.13.2
Successfully installed actionpack-1.11.2
Successfully installed actionmailer-1.1.5
Successfully installed actionwebservice-1.0.0
Installing RDoc documentation for rake-0.6.2...

lib/rake.rb:733:18: unexpected token: '#'
Installing RDoc documentation for activesupport-1.2.5...
Installing RDoc documentation for activerecord-1.13.2...
Installing RDoc documentation for actionpack-1.11.2...

lib/action_controller/code_generation.rb:77:31: unexpected token: '#'

lib/action_controller/code_generation.rb:168:31: unexpected token: '#'
ERROR:  While executing gem ... (NoMethodError)
    undefined method `find_module_named' for nil:NilClass

Ruby Function Time Diff To String

def time_diff time1, time2
diff = time1 - time2

if diff < 1.minute
return diff.ceil.to_s + " seconds"
elsif diff < 1.hour
return (diff / 1.minute).ceil.to_s + " minutes"
elsif diff < 1.day
return (diff / 1.hour).ceil.to_s + " hours"
elsif diff < 7.day
return (diff / 1.day).ceil.to_s + " days"
elsif diff < 1.month
return (diff / 1.week).ceil.to_s + " weeks"
elsif diff < 1.year
return (diff / 1.month).ceil.to_s + " months"
else
return (diff / 1.year).ceil.to_s + " years"
end
end

Daedalus Config to Keep Lighttpd Up Nicely

This daedalus config as well as my previous snippet is meant to supplement chapter 5 of "Lighttpd the painless way".

This config is dependent on having a ~/lighttpd directory setup as described in that manual. Also, you must have the restart.rb script (again from my previous snippet) in the lighttpd folder.

As before, remember to swap out your USERNAME, DOMAIN, and PORT.

The first check here is that a lighttpd process is running. If not then it calls restart.rb which will kill any zombie dispatchers and restart lighttpd.

The second check is more of a departure from the original suggestion. Rather than checking that a specific file is generating the expected output, I go right to the source and verify that lighttpd is responding with an HTTP header on the port you were assigned. This is a pure indication of whether lighttpd is responsive on the correct port. It won't be fouled up by application errors or apache forwarding misconfiguration. More importantly, it won't generate a flood of restarts due to an unrelated code error.

Also, you will notice I set the checkinterval to 10 minutes. I felt this was a good compromise between keeping lighttpd up and saturating the server with unnecessary processing.

name: lighttpd
checkcommand: /bin/ps axww
checkregex: /lighttpd/
onfailcommand: /home/USERNAME/lighttpd/restart.rb
checkinterval: 600 
aftercommandwait: 120

name: lighttpd-external
checkcommand: /usr/local/bin/curl -I http://YOURDOMAIN.com:YOURPORT
checkregex: /^HTTP/s
onfailcommand: /usr/bin/killall -9 lighttpd; /home/USERNAME/lighttpd/restart.rb
checkinterval: 600 
aftercommandwait: 120

Killing rogue dispatch.fcgi processes and starting lighttpd on TextDrive

By using this script to start lighttpd you can be sure you won't be leaving rogues dispatchers around sucking up memory and generally pissing jason off. Don't get caught with your pants down!

Make sure to change USERNAME below, as well as any paths that may be different in your case.

#!/usr/local/bin/ruby
#Modified from Julik's original code posted to TextDrive forums.

pstab = `ps axww`

def kill_fcgi_proc(line)
  its = line.strip.split(/\s+/)
  pid = its[0]
  puts "KILLING #{line}"
  `kill -9 #{pid}`
  sleep(3)
end

if pstab =~ /\/usr\/local\/sbin\/lighttpd -f/
  
  puts "Lighttpd still running."

else

  pstab.scan(/^.*dispatch\.fcgi\s*$/) do |line|
    kill_fcgi_proc line
  end

  pstab = `ps axww`
  
  if pstab =~ /dispatch\.fcgi/
    puts "Error, rogue dispatch.fcgi's still pissing jason off."
  else
    puts "Rogue dispatch.fcgi's cleared, starting lighty!"
    `/usr/local/sbin/lighttpd -f /home/USERNAME/lighttpd/lighttpd.conf`
  end
  
end

suppressing NoMethodError when receiver is nil, within a block

Often in rails you'll do things like

<%= @post.author.name %>


but it may be that you have no post, or the post has no author, and even if that's ok, the above would raise. I came up with a solution that lets you do the following:

<%= ifnil("no author"){ @post.author.name } %>


If at any point the receiver is nil (either @post or #author), execution of the block is stopped and the default value is returned ("no author" in this case, but defaults to nil)

NoMethodError is still raised if you send an invalid message to a non-nil receiver.

Here's the code for ifnil

def ifnil(value=nil)
  yield
  rescue NoMethodError
  raise unless $!.message =~ /:NilClass$/
  value
end

Automatically cipher user password

This allows you to cipher the password of the user automatically upon entry. This way you can allow entry of raw ciphered password via web services etc. as well as keep it ciphered in the database (for instance as a char(32))

require 'md5'
class User < ActiveRecord::Base
        before_save :cipher_password!
    def self.login(login, password)
                password = MD5.new(password).to_s unless password.to_s =~ /^[\dabcdef]{32}$/
                self.find_by_login_and_password(login, password)
        end
        
        private
                def cipher_password!
                        unless password.to_s =~ /^[\dabcdef]{32}$/
                                write_attribute("password", MD5.new(password).to_s)
                                # this is needed for virtual validation
                                @password_confirmation = MD5.new(@password_confirmation).to_s if @password_confirmation
                        end
                end
end


Rails new/add/delete helper

Call: @registered_user_functions( @photo )@, get ( new | edit | delete ) links.
  def registered_user_functions( item = nil, show_new = true )
    # abstract name of html#id to update with javascript
    update_name = item.class.to_s.downcase
    if @session[:user]
      a = "( "
      a << link_to( 'new', :action => 'new' ) + " | " if show_new
      if item # is given to edit or destroy...
        a << link_to_remote( "edit",
              {:url => { :action => "edit", :id => item },
              {:href => url_for( :action => "edit", :id => item ) },
              :update => "#{update_name}-#{item.id}" } )
        a << " | "
        a << link_to_remote( "delete",
              {:url => { :action => "destroy", :id => item },
              {:href => url_for( :action => "destroy", :id => item ) },
              :update => "#{update_name}-#{item.id}",
              :confirm => "really delete this #{update_name}?" } )
      end
      a << " )"
    end
  end

Restart lighttpd script

I use this script to avoid having to do the killall dance on my local dev box constantly when tweaking my lighttpd.conf

#!/bin/sh
sudo killall -9 lighttpd
sudo killall -9 ruby
sudo /opt/local/sbin/lighttpd -f /opt/local/etc/lighttpd.conf


Make the script executable (chmod u+x), put it in your path, invoke by simply typing the name of the script. This also kills off any ruby processes, which lighttpd will restart when it reboots.

The path to lighttpd and the lighttpd.conf files are based on the installation from DarwinPorts - adjust as needed.

Typo current error

NoMethodError in Admin/content#new 
undefined method `text_filter=' for #
app/controllers/admin/content_controller.rb:24:in `new'
Show framework trace 
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.11.1/lib/active_record/base.rb:1200:in `method_missing'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.9.1/lib/action_controller/base.rb:756:in `send'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.9.1/lib/action_controller/base.rb:756:in `perform_action_without_filters'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.9.1/lib/action_controller/filters.rb:295:in `perform_action_without_benchmark'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.9.1/lib/action_controller/benchmarking.rb:41:in `perform_action_without_rescue'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.9.1/lib/action_controller/benchmarking.rb:41:in `measure'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.9.1/lib/action_controller/benchmarking.rb:41:in `perform_action_without_rescue'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.9.1/lib/action_controller/rescue.rb:80:in `perform_action'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.9.1/lib/action_controller/base.rb:356:in `send'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.9.1/lib/action_controller/base.rb:356:in `process'
/usr/local/lib/ruby/gems/1.8/gems/rails-0.13.1/lib/dispatcher.rb:32:in `dispatch'
/home/rsimplicio/web/public/typo/dispatch.fcgi:20
/home/rsimplicio/web/public/typo/dispatch.fcgi:18:in `each_cgi'
/usr/local/lib/ruby/gems/1.8/gems/fcgi-0.8.6.1/./fcgi.rb:597:in `each'
/usr/local/lib/ruby/gems/1.8/gems/fcgi-0.8.6.1/./fcgi.rb:597:in `each_cgi'
/home/rsimplicio/web/public/typo/dispatch.fcgi:18
    
Request
Parameters: None

Show session dump

--- 
:user: !ruby/object:User 
  attributes: 
    name: Robert
    id: "1"
    password: <snipped for security reasons>
    login: Robert
    email: 
:return_to: 
flash: !ruby/hash:ActionController::Flash::FlashHash {}
Response
Headers: {"cookie"=>[], "Cache-Control"=>"no-cache"}

simple last commits patch statistic for darcs

./thisscript.rb 10
will add up the patch stats for the last 10 commits
to the current darcs repo. this differs from the results
for a simple `diff -u --last` as this is the minimal patch
set whereas the script below stats the "edits patch"


#!/usr/bin/ruby
hashes=[]
changelist=`darcs changes --last #{ARGV.first} --xml`
changelist.each_line {
|line|
next unless line =~ /hash='(.*?).gz'/
hashes << $1
}
added, removed = 0, 0
hashes.each {
|hash|
diff=`darcs annotate --match "hash #{hash}"`
diff.each_line {
|l|
added += 1 if l =~ /^[-]/
removed += 1 if l =~ /^[+]/
}
}
puts "+#{added} -#{removed}"

              

            
« Newer Snippets
Older Snippets »
Showing 41-60 of 70 total