rake snippets

Bootstraping your database with rake

Tagged bootstrap, ruby, rails, rake  Languages ruby

In lib/tasks/app.rake:

namespace :db do
  desc "Bootstraps the database"
  task :bootstrap => ['db:schema:load'] do

   { 'Ruby' => 'ruby',
      'JavaScript' => 'javascript',
    }.each do |name, short_name|
      Category.create!(:name => name, :short_name => short_name)
    end

  end
end

How to use Rake for backing up MySQL databases

Tagged mysql, rake, backup  Languages ruby

This is a customized version of this script:

require 'find'

namespace :db do

  desc "Backup the database to a file. Options: DIR=base_dir RAILS_ENV=production MAX=20"

  task :backup => [:environment] do
    datestamp = Time.now.strftime("%Y-%m-%d_%H-%M-%S")
    base_path = ENV["DIR"] || "db"
    backup_base = File.join(base_path, 'backup')
    backup_folder = File.join(backup_base, datestamp)
    backup_file = File.join(backup_folder, "#{RAILS_ENV}_dump.sql.gz")
    FileUtils.mkdir_p(backup_folder)
    db_config = ActiveRecord::Base.configurations[RAILS_ENV]
    pass = ''
    pass = '-p' + db_config['password'] if db_config['password']
    cmd = "mysqldump -P #{db_config['port']} -h #{db_config['host']} -u #{db_config['username']} #{pass} #{db_config['da
tabase']} -Q --add-drop-table -O add-locks=FALSE -O lock-tables=FALSE | gzip -c > #{backup_file}"
    sh cmd
    dir = Dir.new(backup_base)
    all_backups = dir.entries[2..-1].sort.reverse
    puts "Created backup: #{backup_file}"
    max_backups = (ENV["MAX"] || 20).to_i
    puts max_backups
    unwanted_backups = all_backups[max_backups..-1] || []
    for unwanted_backup in unwanted_backups
      FileUtils.rm_rf(File.join(backup_base, unwanted_backup))
      puts "deleted #{unwanted_backup}"
    end
    puts "Deleted #{unwanted_backups.length} backups, #{all_backups.length - unwanted_backups.length} backups available"

  end

end

How to render a view or partial from a Rake task, model or anywhere

Tagged actionview, render, rake, view, rails, routes  Languages ruby

This is tested with Rails 3.0.7 and will most likely change in future versions of Rails:

# @newsletter in the view file
assigns = { :newsletter => self }

routes = Rails::Application.routes # Rails => YourApp
routes.default_url_options = { :host => 'xxx.com' }

av = ActionView::Base.new(Rails::Application::Configuration.new(Rails.root).paths.app.views.first, assigns)
av.class_eval do
  include ApplicationHelper
  include routes.url_helpers
end

self.html = av.render :template => 'newsletters/show'

After some experimentation I ended up with this code:

class RenderHelper
  class << self
    def render(assigns, options, request = {})
      request = { 
        "SERVER_PROTOCOL" => "http", 
        "REQUEST_URI" => "/",
        "SERVER_NAME" => "localhost", 
        "SERVER_PORT" => 80
      }.merge(request)

      av = ActionView::Base.new(ActionController::Base.view_paths, assigns)
      
      av.config = Rails.application.config.action_controller
      av.extend ApplicationController._helpers
      av.controller = ActionController::Base.new
      av.controller.request = ActionController::Request.new(request)
      av.controller.response = ActionController::Response.new
      av.controller.headers = Rack::Utils::HeaderHash.new

      av.class_eval do
        include Rails.application.routes.url_helpers
      end

      av.render options 
    end
  end
end

And this is how I use it:

RenderHelper.render(:newsletter => self, :template => 'mailchimp/daily')