10 Things You Didn't Know Rails Could do


Rails Conference2012のスライドらしいです。
10 Things You Didn't Know Rails Could do // Speaker Deck
とても素晴らしい資料だったので、自分用にメモ。
実は10thingsじゃなく、42things。

気になったとこ

3.Remind You of Things
rake notes
rake notes:custom ANNOTATION=JEG2

notes:todo, notes:fixme 以外にも独自のものが付けれる。

4.Keep You Entertained

リンク先の右上に注目。
Rubydramas.com - Your guide to the last ruby drama

9.Understand Shorthand Migration

stringの省略やindex書けるのは知ってましたが
limitも{}で書けるんですね。

rails g resouce user name:string email:string tokern:string{6} bio:text
rails g resouce user name:index email:uniq token:string{6} bio:text
13 Import Your CS Data

excel → csv 対応かな。utf-8で保存し忘れがありそうだけど。
path生成時のアスタリスクは無しでも動くような気がする。

Name,Email
James,james@example.com
Dana,dana@example.com
Summer,summer@example.com
require 'csv'

namespace :userd do
  desc "Import users from a CSV file"
  task :import => :environment do
    path = ENV.fetch("CSV_FILE") {
      File.join(File.dirname(__FILE__), *%w[.. .. db data users.csv])
    }
    CSV.foreach(path, headers: true, header_converters: :symbol) do |row|
      User.create(row.to_hash)
    end
  end
end
14.Store CSV in Your Database

なるほど。

class Article < ActiveRecord::Base
  require 'csv'
  module CSVSerializer
    module_function
    def load(field) field.to_s.parse_csv end
    def dump(object) Array(object).to_csv end
  end
  serialize :categories, CSVSerializer
  
  # …
  
  attr_accesible :body, :subject, :categories
end
15.Use Different a Database for Each User

ユーザ毎やsubdomain毎にDBを切り替える方法。
(これやりたかったんですよ。)

  def connect_to_user_database(name)
    config = ActiveRecord::Base.configurations['develpment']
                               .merge('database' => 'db/#{name}.sqlite3')
    ActiveRecord::Base.establish_connection(config)
  end
require 'user_database'


migrate task。

namespace :db do
  desc "Add a new user database"
  task :add => %w[environment load_config] do
    name = ENV.fetch("DB_NAME") { fail "DB_NAME is required" }
    connect_to_user_database(name)
    ActiveRecord::Base.connection
  end
 
  namespace :migrate do
    desc "Migrate all user databases"
    task :all => %w[environment load_config] do
      ActiveRecord::Migration.verbose = ENV.fetch("VERBOSE", "true") == "true"
      Dir.glob("db/*.sqlite3") do |file|
        next if file == "db/test.sqlite3"
        connect_to_user_database(File.basename(file, ".sqlite3"))
        ActiveRecord::Migrator.migrate(
          ActiveRecord::Migrator.migrations_paths,
          ENV["VERSION"] && ENV["VERSION"].to_i
        ) do |migration|
          ENV["SCOPE"].blank? || (ENV["SCOPE"] == migration.scope)
        end
      end
    end
  end
end


subdomain切替用。

class ApplicationController < ActionController::Base
  protect_from_forgery
  
  before_filter :connect_to_database

  private
  def connect_to_database
    connect_to_user_database(request.dubdomains.first)
  end
end


rails console。

$ rails c
> connect_to_user_databae("ruby_rogues")
23.Write Files Atomically

File.atomic_write
これ知りませんでした。他のprocessやthreadに生成途中のファイルを見せたくない場合に使うようです。
ソースを見ると、Tempfileで生成したのち、mvしています。
File リファレンス

24.Merge Nested Hashes

deep_merge

25.Remove Specific Keys From a Hash

except

32. Use Blocks to Avoid Assignments in Views

計算するメソッドをcallし、その結果を他で使用するようなviewがあった場合

<tr>
  <td>Tax</td>
  <td><%= number_to_currency(tax = calculate_tax(@cart.total)) &></td>
</tr>
<tr>
  <td>Total</td>
  <td><%= number_to_currency(@cart.total + tax) &></td>
</tr>


blockを使って、こんな風に書ける。

<% calculate_tax @cart.total do |tax| %>
<tr>
  <td>Tax</td>
  <td><%= number_to_currency tax &></td>
</tr>
<tr>
  <td>Total</td>
  <td><%= number_to_currency(@cart.total + tax) &></td>
</tr>
<% end %>
module CartHelper
  def calculate_tax(totak, user = current_user)
    tax = TaxTable.for(user).calculate(total)
    if block_given?
      yield tax
    else
      tax
    end
  end
end
33.Generate Multiple Tags at Once

content_tag_forでループ。(from Jose Valim)

<% @articles.each do |article| %>
  <%= content_tag_for(:div, article) do %>
    <h2><%= article.subject ></h2>
  <% end %>
<% end %>
<%= content_tag_for(:div, @articles) do |article| %>
  <h2><%= article.subject ></h2>
<% end %>
37.Inspire Theme Songs About Your Work

なんぞこれ。ググったらでてきた。
Ruby Hero Tenderlove! - Ron Evans - Farmhouse Conf 2011


愛されまくってる感たっぷりだが、これは恥ずかしいな
Ruby Heroも大変やなー。


あとで

38. config_exceptons_app = routes の使い方がよくわかんなったので
あとで調べる