Using rails 2 views in rails 3.2

Usage
Just keep using your deprecated block helpers, they can be converted once the transition to rails 3 is complete.

<% form_for xxx do |f| %>
  still works
<% end %>

Code

  # make <% helper do %> work
  block_concat = [
    [ActionView::Helpers::FormHelper, :fields_for],
    [ActionView::Helpers::FormBuilder, :fields_for],
    [ActionView::Helpers::FormHelper, :form_for],
    [ActionView::Helpers::FormTagHelper, :form_tag],
    [ActionView::Helpers::TagHelper, :content_tag],
    [ActionView::Helpers::UrlHelper, :link_to],
    [ActionView::Helpers::JavaScriptHelper, :javascript_tag],
    [ActionView::Helpers::CacheHelper, :cache],
  ]

  ERB_EXTENSION = '.erb'.freeze

  block_concat.each do |klass, method|
    klass.class_eval do
      without = "#{method}_without_concat".to_sym
      alias_method without, method
      define_method(method) do |*args, &block|
        result = send(without, *args, &block)
        if block && block.source_location.first.include?(ERB_EXTENSION) # called from a erb template ?
          (@template || self).concat(result) # deprecated erb concat helper
          ""
        else
          result
        end
      end
    end
  end

Upgrading from rails 2 mailer to rails 3 without using new api

Converting all your mailers to the new api in a single commit is pretty daunting and makes them less readable / reusable since now everything has to fit into one big hash at the end of each method. This little patch keeps mailer methods that use the old api working while allowing to use the new api, a smooth transition path!

Usage

class UserMailer < ApplicationMailer::Base
  include DeprecatedMailerAPI

  def welcome
    to "me@example.com"
    from "you@example.com"
    subject "blah"
  end
end

UserMailer.deliver_welcome

Code

  module DeprecatedMailerAPI
    # call build_mail if mail was not used
    def process(*args)
      old = @_message
      super
      unless @mail_was_called
        @_message = old
        build_mail
      end
    end

    def from(xxx=:read)
      mail_cache(:from, xxx)
    end

    def recipients(xxx=:read)
      mail_cache(:to, xxx)
    end

    def cc(xxx=:read)
      mail_cache(:cc, xxx)
    end

    def bcc(xxx=:read)
      mail_cache(:bcc, xxx)
    end

    def reply_to(xxx=:read)
      mail_cache(:reply_to, xxx)
    end

    def content_type(xxx=:read)
      mail_cache(:content_type, xxx)
    end

    def body(xxx=:read)
      mail_cache(:body, xxx)
    end

    def part(options)
      key = case options[:content_type]
      when Mime::TEXT.to_s then :text
      when Mime::HTML.to_s then :html
      else
        raise "Unuspported content_type #{options[:content_type].inspect}"
      end
      @mail_cache ||= {}
      @mail_cache[:parts] ||= {}
      @mail_cache[:parts][key] = options[:body]
    end

    def subject(xxx=:read)
      mail_cache(:subject, xxx)
    end

    def build_mail
      if @mail_cache[:parts]
        mail(@mail_cache.except(:parts, :content_type)) do |format|
          @mail_cache[:parts].each do |f,b|
            format.send(f) { render :text => b }
          end
        end
      else
        mail(@mail_cache)
      end
    end

    def mail_cache(k,v)
      @mail_cache ||= {}
      if v == :read
        @mail_cache[k]
      else
        @mail_cache[k] = v
      end
    end

    def self.included(base)
      class << base
        alias_method :method_missing_without_deprecated, :method_missing

        # convert old create/deliver_foo to foo().deliver
        def method_missing(name, *args, &block)
          if match = /^(create|deliver)_([_a-z]\w*)/.match(name.to_s)
            mail = method_missing_without_deprecated(match[2], *args, &block)
            match[1] == "create" ? mail : mail.deliver
          else
            method_missing_without_deprecated(name, *args, &block)
          end
        end
      end
    end
  end

Upgrading from rails 2 router to rails 3 while keeping :collection and :member

We are just upgrading our router from rails 2 to 3 and wanted to keep resource :member => {:foo => :get} working so we do not have to rewrite everything at once and can roll out the change and then refactor in a separate step.

Usage

# use this
resources :users, :member => {:invite => :post}, :collection => {:search => :get}

# instead of
resources :users, :member => {:invite => :post}, :collection => {:search => :get} do
  member do
   post :invite
  end
  collection do
    get :search
  end
end

Code

# keep resource with :member / :collection working to reduce diff
ActionDispatch::Routing::Mapper.class_eval do
  def resources(*args, &block)
    block = support_deprecated_options(args, block)
    super(*args, &block)
  end

  def resource(*args, &block)
    block = support_deprecated_options(args, block)
    super(*args, &block)
  end

  private

  def support_deprecated_options(args, original_block)
    options = args.last
    if options.is_a?(Hash) && (options[:member] || options[:collection])
      collection = options.delete(:collection)
      member = options.delete(:member)
      Proc.new do
        collection { add_deprecated_actions(collection) } if collection
        member { add_deprecated_actions(member) } if member
        original_block.call if original_block
      end
    else
      original_block
    end
  end

  def add_deprecated_actions(collection)
    collection.each { |name, method| match name, :via => (method == :any ? nil : method) }
  end
end

Trusted wildcard SSL certs for localhost on osx / mac

Screen Shot 2013-11-27 at 6.58.11 PM

Create cert

openssl genrsa 2048 > host.key
openssl req -new -x509 -nodes -sha1 -days 3650 -key host.key > host.cert
#[enter *.localhost.dev for the Common Name]
openssl x509 -noout -fingerprint -text < host.cert > host.info
cat host.cert host.key > host.pem

Trust cert

sudo security add-trusted-cert -d -r trustRoot \
 -k /Library/Keychains/System.keychain host.cert

boxen / puppet config

# nginx.conf
server {
  listen 80;
  listen 443 default ssl;

  ssl_certificate     <%= scope.lookupvar "nginx::config::configdir" %>/ssl/localhost.crt;
  ssl_certificate_key <%= scope.lookupvar "nginx::config::configdir" %>/ssl/localhost.key;

  server_name *.localhost *.localhost.dev;



# nginx.pp
  file { "${nginx::config::configdir}/ssl":
    ensure => 'directory'
  }

  $cert = "${nginx::config::configdir}/ssl/localhost.crt"

  exec {"trust-nginx-cert":
    command => "sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ${cert}",
    require => File[$cert],
    user => root,
  }

  file { $cert:
    ensure => present,
    source => 'puppet:///modules/company-name/ssl/localhost.crt',
    notify  => Service['dev.nginx']
  }

  file { "${nginx::config::configdir}/ssl/localhost.key":
    ensure => present,
    source => 'puppet:///modules/company-name/ssl/localhost.key',
    notify  => Service['dev.nginx']
  }