Flowdock

Notes posted by james

RSS feed
February 12, 2010
1 thank

re: Options

@ramanavel - The options are dependent on the cache store that you’re using. You’ll need to have a look at what the cache store you’re using allows.

e.g. MemCacheStore allows the use of time criteria based :expires_in, most of the cache stores don’t.

http://guides.rubyonrails.org/caching_with_rails.html might provide a little more information.

November 5, 2008
0 thanks

re: james' note incorrect

kieran is correct, my note is incorrect, it was not meant for ActionMailer::Base

November 5, 2008
0 thanks

RERE: 1 render definition for many actions (cleaner)

@arronwashington. Ah, so that’s the motivation for using default_render, thanks for clearing that up, thanks :)

November 4, 2008
0 thanks

re: Specifying :include no longer necessarily joins the association

I have seen how :include does not nessisarily perform a join during that SQL query, if you need the join to occur then, rather then tricking AR (“forcing”), use :joins instead of :include to ensure the joins occur.

November 4, 2008 - (v1.0.0 - v2.1.0)
1 thank

1 render definition for many actions (cleaner)

@arronwashington, you can just call render rather then using instance_eval to overwrite default_render, for example:

before_filter :render_filter, :only => [:zombies, :cool_zombies]

def zombies
  @zombies = Zombie.find(:all)
end

def cool_zombies
  @zombies = Zombie.find(:all, :conditions => { :eats_humans => false, :is_hippie => true })
end

protected

def render_filter
  # without instance_eval or overwriting default_render
  render :template => 'zombies/all'
end
July 25, 2008 - (v1.0.0 - v2.1.0)
4 thanks

haml, an alternative to ERb

Want something nicer looking (and currently, faster!) than using ERb for your views? Have a look at haml (and it’s companion, sass, for stylesheets). It will make you feel all fuzzy on the inside, I promise :P.

ERb example

<div id="profile">
  <div class="left column">
    <div id="date"><%= print_date %></div>
    <div id="address"><%= current_user.address %></div>
  </div>
</div>

haml equivalent

#profile
  .left.column
    #date= print_date
    #address= current_user.address

Shifting to haml from ERb feels strange at first, but after about 20 minutes it starts to feel nice. A little longer and you’ll really start to notice your productivity (and of course, happiness) increase! :). I’ve starting shifting all new projects developed at our work office over to using haml (and sass), it’s been fantastic!

At first I came across a few things that I couldn’t do in haml, though every time a quick read of the overview doc page would show me a simple syntax for overcoming that issue! :) (which out of interest, is located here: http://haml.hamptoncatlin.com/docs/rdoc/classes/Haml.html)

Give the tutorial a shot if you’re interested: http://haml.hamptoncatlin.com/tutorial

July 25, 2008 - (v1.0.0 - v2.1.0)
0 thanks

render template file different from your action (method) name - alternative

Alternative ways to render templates for actions

# Renders the template for foo (foo.html.erb, foo.haml.erb, foo.text.html.haml, whatever :P)
def foo
end

# Renders the template that would be rendered in foo
# (but without the foo controller action being invoked)
def bar
  render :action => 'foo'
end

# Similar to what bar does, but render's a specifically named template
def roar
  render :template => 'foo'
end

# Similar to what roar does, but render's a template
# from outside of the current controller's views directory
def boo
  render :template => 'global/something'
end
July 24, 2008 - (v1.0.0 - v2.1.0)
0 thanks

Extract plain text body from TMail parsed email

Here’s a monkey patch for TMail::Mail I wrote to recurse through a message and extract all plain text body components of that message, returning an Array. For most use cases, the resulting Array will contain one String element.

Currently I put this code in a file called lib/tmail_extensions.rb and require ‘tmail_extensions’ in environment.rb

module TMail
  class Mail
    def plain_text_body
      gather_plain_text_parts(self).flatten
    end

  private
    def gather_plain_text_parts(part)    
      returning [] do |message|
        message << part.body.strip if part.content_type == 'text/plain'        
        part.parts.each { |p| message << gather_plain_text_parts(p) }
      end
    end
  end
end
July 24, 2008 - (v2.1.0)
20 thanks

automatically generate scopes for model states

or better known as “throw on some more tasty meta-programming” :). Given an example of a model which has a state (String) which must from a set of defined values, e.g. pending, approved, denied.

class User < ActiveRecord::Base
  STATES = [ 'pending', 'approved', 'denied' ]

  validates_inclusion_of :state, :in => STATES

  # Define a named scope for each state in STATES
  STATES.each { |s| named_scope s, :conditions => { :state => s } }
end

This automatically defines a named_scope for each of the model states without having to define a named_scope manually for each state (nice and DRY).

July 24, 2008 - (v1.0.0 - v2.1.0)
1 thank

Custom environment constants

Custom environment level constants can be passed in to your rails application (server, console, whatever) like this):

# bash, tcsh, whatever shell
GAMEMODE=pregame script/server

Within rails this constant can be accessed by

ENV['GAMEMODE']
=> "pregame"

ENV['DOES-NOT-EXIST']
=> nil
July 23, 2008 - (v1.0.0 - v2.1.0)
2 thanks

subdomains from request

Useful for discovering what domain/subdomain(s) the current request came from (Rails application may operate differently depending on which subdomain is passed in, this is a great way to segment functionality using the route).

request.host.split('.')

Doesn’t get much simpler than that :).

Likewise if you want to see only the subdomain component(s). Given a domain, example.com

request.host.gsub('example.com', '').split('.')
July 23, 2008 - (<= v2.1.0)
9 thanks

Easy and effective admin authentication

Great for use within an AdminController (in which all other administrative controllers inherit from AdminController).

class AdminController < ApplicationController
  before_filter :authenticate

  def authenticate
    authenticate_or_request_with_http_basic('Administration') do |username, password|
      username == 'admin' && password == 'password'
    end
  end
end
July 23, 2008 - (<= v2.1.0)
9 thanks

perform update_all scoped within a has_many collection

For example: having two models, User and Message (user has_many messages, each message has a boolean flag called ‘read’). You want to mark all messages as read for a particular user.

Mark all messages as read for a particular user

Message.update_all({:read => true}, {:id => user.messages})
July 22, 2008 - (v2.1.0)
4 thanks

Rails 2.1 migrations

Things to take note of are the lack of ‘column spam’, which didn’t convey much semantic meaning. Also the combination of multiple fields per line with the same type.

references is also a nice helper to convey relationship information (t.references :role is equivilant to t.integer :role_id). references also takes another parameters, see the method for more details.

code

class CreateUsers < ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.string :first_name, :last_name, :email
      t.text :address
      t.date :date_of_birth
      t.references :role

      t.timestamps
    end

    add_index :users, :email
  end

  def self.down
    drop_table :users
  end
end
July 22, 2008 - (v1.0.0 - v2.1.0)
4 thanks

Better slug generation (essentially a to_param replacement)

Monkey Patching String

class String
  def slugify
    returning self.downcase.gsub(/'/, '').gsub(/[^a-z0-9]+/, '-') do |slug|
      slug.chop! if slug.last == '-'
    end
  end
end

In a model, or wherever

def to_param
  # Don't need the id here if we're looking up the model by the stored slug.
  "#{id} #{title}".slugify
end