? Earlier 16 items total Later ?

On this page:?

Create a date-based archive from a model

All the functions it needs to run are included. You might already have a 'delta' and 'find_all_by_date' function some where in your code. You could easily use those instead.

Customize the 'find_all_by_date' function to include, say, only published posts.

Add this to your model.
def self.find_all_by_date(year = nil, month = nil, day = nil)
  if year != nil
    from, to = delta(year, month, day)
    find(:all, 
         :conditions => [ %{ created_at BETWEEN ? AND ? }, from, to],
         :order => 'created_at DESC')
  else
    find(:all, 
         :order => 'created_at DESC')
  end
end

def self.list_years()
  list_date_part(:year)
end

def self.list_months(year)
  list_date_part(:month, year)
end

def self.list_days(year, month)
  list_date_part(:day, year, month)
end

def self.list_date_part(part, *fixed_parts)    
  find_all_by_date(*fixed_parts).map{ |record| record.created_at.send(part) }.uniq
end

def self.delta(year, month = nil, day = nil)
  from = Time.mktime(year, month || 1, day || 1)

  to   = from + 1.year
  to   = from + 1.month unless month.blank?    
  to   = from + 1.day   unless day.blank?
  to   = to.tomorrow    unless month.blank? or day
  return [from.midnight, to.midnight]
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):





        Label
        us.boygeni.mysql-session-sweeper
        LowPriorityIO
        
        ProgramArguments
        
                /users/defeated/Sites/rails_apps/boygenius/script/runner
                'ActiveRecord::Base.connection.delete("DELETE FROM sessions WHERE updated_at < now() - INTERVAL 1 HOUR")'
        
        RunAtLoad
        
        StartInterval
        3600


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

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


? Earlier 16 items total Later ?