datamapper(dm-core) 1.1.0では0.10.0からdeprecatedになっていた明示的なINの利用が出来なくなりました。明示的なINと暗黙的なINって何なのかというと下記の様な違いです。

# implicit
Foo.all(:id.in => [1, 2, 3])

# explicit
Foo.all(:id => [1, 2, 3])

対象がArrayだと自動的にINになるんですね。1.0.2で使ってたけどdeprecatedの表示は出てなかった気がするけどなあ。ヤラレタ。

つい先日、LokkaにもCI環境が整ったのでデグレしないようにテスト駆動バグ修正していくことにしました。

RuntimeError - explicit use of 'in' operator is deprecated - Issues - komagata/lokka - GitHub

$ gem install cmdline-fu
% cmdline-fu matching ssh               
# Copy ssh keys to user@host to enable password-less ssh logins.
$ssh-copy-id user@host

# start a tunnel from some machine's port 80 to your local post 2001
ssh -N -L2001:localhost:80 somemachine

# output your microphone to a remote computer's speaker
dd if=/dev/dsp | ssh -c arcfour -C username@host dd of=/dev/dsp

# Mount folder/filesystem through SSH
sshfs name@server:/path/to/folder /path/to/mount/point

サイトの方ちゃんと見に行ってみると、「こっちのがいいだろう」とか「それ動かなくね?」とかツッコミが多いので常用するワンライナーを探してる場合はちゃんと見た方がいいかも。

TerminalでちょこっとWeb上のテキストが欲しい時が結構あるのでcss_selector.gemというのを作りました。

標準入力からCSS Selectorで指定した物の結果を改行繋ぎで出すだけのコマンドです。

deviseでログイン後のURLを設定する方法。

deviseではログイン後にはデフォルトでroot_pathに移動するようになってる。それを変えたい。

devise / lib / devise / controllers / helpers.rb

def after_sign_in_path_for(resource_or_scope)
  scope = Devise::Mapping.find_scope!(resource_or_scope)
  home_path = "#{scope}_root_path"
  respond_to?(home_path, true) ? send(home_path) : root_path
end

上記の様にresource(普通はUser)のroot_pathが設定されてればそっちに行くようになってるので下記の様にuser_root_pathに何かを設定すればいい。

# config/routes.rb:
Foo::Application.routes.draw do
  match '/snippets' => 'snippets#index', :as => :user_root
end

ログイン後に/snippetsに行くようになった。

% gem install haml2slim
% ls app/views/emotions 
_form.html.haml edit.html.haml  index.html.haml new.html.haml   show.html.haml
% haml2slim app/views/emotions 
% ls app/views/emotions 
_form.html.haml _form.html.slim edit.html.haml  edit.html.slim  index.html.haml index.html.slim new.html.haml   new.html.slim   show.html.haml  show.html.slim
# app/views/emotions/show.html.slim: 
p#notice= notice
p
  b Body:
  = @emotion.body
p
  b Kind:
  = @emotion.kind
= link_to 'Edit', edit_emotion_path(@emotion)
= link_to 'Back', emotions_path

OMG!

Generators Slim - Issues - plataformatec/devise - GitHub

I'm exec this generate for slim, but the code created is erb...

$ rails g devise:views usuarios -e slim
  create  app/views/usuarios
  create  app/views/usuarios/confirmations/new.html.erb
  create  app/views/usuarios/mailer/confirmation_instructions.html.erb
  create  app/views/usuarios/mailer/reset_password_instructions.html.erb
  create  app/views/usuarios/mailer/unlock_instructions.html.erb
  create  app/views/usuarios/passwords/edit.html.erb
  create  app/views/usuarios/passwords/new.html.erb
  create  app/views/usuarios/registrations/edit.html.erb
  create  app/views/usuarios/registrations/new.html.erb
  create  app/views/usuarios/sessions/new.html.erb
  create  app/views/usuarios/shared/_links.erb
  create  app/views/usuarios/unlocks/new.html.erb

josevalim February 11, 2011 | link

You need devise master to do that.

READMEに書いてあるけど、deviseでhaml or slim(-eオプション)使いたかったら1.1.7じゃ駄目でmaster使えとのこと。1.2rcが正式になったら使えるようになるかも。

RubyでのUUIDのversion 1の使い方。

gem install uuid
>> require 'rubygems'
=> true
>> require 'uuid'
=> true
>> UUID.new
=> MAC: 58:55:ca:f3:26:47  Sequence: 9499
>> UUID.new.generate
=> "bc66c930-22f1-012e-251b-5855caf32647"
>> UUID.new.generate :compact
=> "be64e03022f1012e251b5855caf32647"

:compactはハイフンを取ってくれる。


How to use UUID Version 1 in Ruby.

:compact option omits the hyphens.

# Gemfile:
gem 'devise'
% bundle
% rails g devise:install
% rails g devise:views
% rails g devise user
% rails g controller home index
% rake db:migrate
# config/environments/development.rb:
Foo::Application.configure do
  # ...
  config.action_mailer.default_url_options = { :host => 'localhost:3000' }
end
# config/routes.rb:
Foo::Application.routes.draw do
  root :to => 'home#index'
  # ...
end
# app/views/layouts/application.html.erb:  
<p><%= link_to 'Sign in', [:new, :user_session]  %></p>                                                                                                               
<p><%= link_to 'Sign up', [:new, :user_registration]  %></p>
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
<%= yield %>
% curl https://github.com/svenfuchs/rails-i18n/raw/master/rails/locale/ja.yml -o config/locales/ja.yml
% curl https://gist.github.com/raw/833169/54d19c523f6a608e732d4e9a6606a6d6cbec7f8e/devise.ja.yml -o config/locales/devise.ja.yml

RailsのオススメファイルアップロードプラグインのPaperclipですが、最新版(2.1.4)で嬉しい機能が増えてました。

  • ImageMagick(convertコマンド)に自由にオプションを渡せるようになった。
  • 画像が無いときのパスを指定できるようになった。

これは嬉しい。ソース内のコメントの例では、アップされた画像をlargeとnegativeというstyleに分け、両方にprofileやexif情報を削除する-stripオプションを適応し、negativeには補色で補完する(つまり反転?)-negateオプションを適応してます。

class User < ActiveRecord::Base
  has_attached_file :avatar,
    :styles => {
      :large => "300x300",
      :negative => "100x100"},
    :convert_options => {
      :all => "-strip",
      :negative => "-negate"}
end

RMagickや他のAPIを使わず、直接convert使ってる利点が生かされてますな。 他にも-monochromeオプションでモノクロにしたりとか色々出来そうです。

画像無いときのパス指定は、「あれ?これ指定できないの?」ぐらいだったんで俺がすっきりしただけですが。

以前にも書きましたが、Capistrano利用時にはアップ画像を/public/system以下に置きたいのでオプション指定が必要です。

いちいち指定してたらModelがキモくなるので通常、下記を使ってます。

config/initializers/paperclip.rb:

module Paperclip::ClassMethods
  def has_attached_file_with_default(name, options = {})
    default = {
      :path => ":rails_root/public/system/:class/:attachment/:id/:style/:basename.:extension",
      :url => "/system/:class/:attachment/:id/:style/:basename.:extension",
      :default_style => :normal,
      :default_url => "/images/:class/:attachement/missing_:style.png" 
    }

    has_attached_file_without_default(name, default.update(options))
  end

  alias_method_chain :has_attached_file, :default
end

config/initializers/以下は一番最後(pluginよりあと)に読まれるのでこういうアプリの本質的でない部分の変更には向いてますな。

RMagickインストール地獄にハマってる方はぜひご検討ください! (Debian etch、CentOS 5.2共にimagemagick/ImageMagickパッケージを入れるだけで済みます)

参照: Capistrano利用時のPaperclip

大体の画像系と同じようにnilとかを入れるだけでOK。

% ./script/console
Loading development environment (Rails 2.1.0)
>> grave = Grave.first
=> (略)
>> grave.overview.url
=> "/system/graves/overviews/1/normal/test_picture_large.gif" 
>> grave.overview = nil
=> nil
>> grave.save
=> true
>> grave.overview.url
=> "/overviews/normal/missing.png"

しかも、削除した場合のURLが自動的にmissing.pngに変わってる。

この勝手な挙動が嫌いな人もいるかもしれないけど面倒臭がりの俺としては嬉しい。

画像があるかどうかは、grave.overview.exists? で分かる。

thoughtbot: Paperclip File Attachments

Requirements

Only ImageMagick, which you can install quite easily install via apt, yum, or port, or the package manager of your choice.

あとやっぱりRMagick無くても動く!そういやImageMagick自体が問題なんじゃなくて、殆どの場合、パッケージのImageMagickが言語バインディングと合わないことが問題だったんだよね。PureRubyで再実装しかないと思ってた。頭良いな作者。