Archive for April, 2008

sex spam

“Let us show you the way to the true meaning of the big bang theory” — Nataliya-oludesnu@JobsClosetoHome.com

google analytics for rails production environment

# assuming a partial located in views/shared
# that contains the google analytics script body
def render_google_analytics_script
  render :partial => "/shared/google_analytics" if Rails.env == "production"
end

# render from layouts
<%= render_google_analytics_script %>

sex spam

“Does your size ruin your life? Our product will stop that …” — “Dannie Armstrong”

paginated record numbers

# application_helper.rb
# record numbering inside paginated admin index views
def paginated_record_number(offset)
  # TODO find out will_paginate page_count query
  page = params[:page] ? params[:page].to_i : nil
  (page ? page - 1 : 0) * ( params[:per_page] || 30) + offset + 1
end

# use in views like so
<%= paginated_record_number(idx) %>

link_to_has_one

# Creates 'Show AssociatedResource' or 'New AssociatedResource' links
# based on wether the specified has_one association exists or not.
# The optional options parameter is passed through to link_to as html_options.
# Since this helper relies on record identification, there is no way to pass
# all the other url_for options, as far as I can see
# ---------------------------------------------------------------------------
# Use in your views like so:
# <%= link_to_has_one @post, :comment %>
# <%= link_to_has_one @post, :comment, "What say you?" %>
# <%= link_to_has_one @post, :comment, "What say you?", :class => "oldskool" %>
def link_to_has_one(parent, has_one_association_name, options = {})
  has_one_association_name = has_one_association_name.to_s.underscore
  child = has_one_association_name.camelize
  child_path = "#{parent.class.to_s.underscore}_#{has_one_association_name}_path"
  if parent.send(has_one_association_name)
    name = options[:new_name] ? options[:new_name] : "Show #{child}"
    link_to name, self.send(child_path, parent), options
  else
    name = options[:existing_name] ? options[:existing_name] : "New #{child}"
    link_to name, self.send("new_#{child_path}", parent), options
  end
end

named_scope features and gotchas

# Examples mostly taken from Ryan Daigle's blog.
# http://ryandaigle.com/articles/2008/3/24/what-s-new-in-edge-rails-has-finder-functionality
# this shall serve as a reminder for me!

# WORKS but actually breaks coding conventions
# well, at least in most cases if you respect print margins ;)
# (multiline blocks/lambdas(?) are supposed to be enclosed in do/end

named_scope :created_by_account, lambda { |account|
  { :conditions => [ "created_by = ?", account.id ] }
}

# DOES NOT WORK
# ArgumentError: tried to create Proc object without a block
# Most probably this is due to the way that named_scope extensions can be defined

named_scope :created_by_account, lambda do |account|
  { :conditions => [ "created_by = ?", account.id ] }
end

# named_scope extensions
# I guess because of the way do/end is used here,
# it is not possible to use do/end with lambda

named_scope :inactive, :conditions => {:active => false} do
  def activate
    each { |i| i.update_attribute(:active, true) }
  end
end

# original comment by Pratik Naik on March 27, 2008 @ 08:56 PM

named_scope :recent, :conditions => ['created_at > ?', 1.week.ago]

# That is really a bad example. As the conditions gets evaluated at load time,
# it’ll end up giving you inaccurate results in production
# where models get loaded only once.

# "Correct" way would be :

named_scope :recent, lambda {
  { :conditions => ['created_at > ?', 1.minute.ago] }
}

# Store named scopes
active = User.scoped(:conditions => {:active => true})
recent = User.scoped(lambda { { :conditions => ['created_at > ?', 1.minute.ago] } })
recent_active = recent.active
recent_active.each { |u| ... }

# count and statistic methods

user.active.recent.count #=> 23
user.active.recent.sum(:age) #=> 391

watching activerecord

# This greatly helps learning what ActiveRecord does!

# All credits go to Jamis Buck at
# http://weblog.jamisbuck.org/2007/1/31/more-on-watching-activerecord

# environment.rb
def log_to(stream)
  ActiveRecord::Base.logger = Logger.new(stream)
  ActiveRecord::Base.clear_active_connections!
end

# in irb or script/console or environment.rb
log_to(STDOUT)

# or create new streams
buffer = StringIO.new
log_to(buffer)
puts buffer.string

sex spam

“Even Elephant will be jealous of your trunk.” — Bouma [Chrys-gitumtne@HINTON-GRUSICH.COM]

has_many_polymorphs and rails weirdness

When using has_many_polymorphs tagging generator, it will create appropriate Tag and Tagging models. However, if one uses this generator BEFORE using, say, rspec_scaffold for the same two models, Rails bails with

The name ‘PopulationTag’ is reserved by Ruby on Rails.
Please choose an alternative and run this generator again.

This confused me in the beginning! However, to overcome this, simply rename your model files before running the rspec_scaffold generator (of course renaming them back afterwards).

To workaround this issue in the first place, be sure to generate rspec_scaffolds BEFORE using the tagging generator that comes with has_many_polymorphs

foreach and inject and map defined for and in trxl

FOREACH_IN = <<-PROGRAM
  foreach_in = fun(enumerable, body) {
    _foreach_in_(enumerable, body, 0);
  };
  _foreach_in_ = fun(enumerable, body, index) {
    if(index < SIZE(enumerable) - 1)
      body(enumerable[index]);
      _foreach_in_(enumerable, body, index + 1)
    else
      body(enumerable[index])
    end
  };
PROGRAM

INJECT = <<-PROGRAM
  inject = fun(memo, enumerable, body) {
    _inject_(memo, enumerable, body, 0);
  };
  _inject_ = fun(memo, enumerable, body, index) {
    if(index < SIZE(enumerable) - 1)
      _inject_(body(memo, enumerable[index]), enumerable, body, index + 1)
    else
      body(memo, enumerable[index])
    end
  };
PROGRAM

MAP = <<-PROGRAM
  require 'stdlib/inject';
  map = fun(enumerable, body) {
    b = body; # WORK AROUND a bug in Trxl::Environment
    inject([], enumerable, fun(memo, e) { memo << b(e); });
  };
PROGRAM