Rails3.XXで画像アップロード

こんばんはこんばんはue10000です。


Rails3.0.8で画像アップロードしたくなりました。


という訳で今は何が標準?ってことでググッテミマシタ。


paperclip
dragonfly


あたりがよく使われてるみたいですね。



paperclipのほうが記事も多くデファクトに近い感じです。使い方はattachment_fuとかrails2系で使っていた人には違和感なさそう。機能もデータストアにAmazonS3に対応してたりと盛りだくさん。自前でガリガリ書いてた昔に比べると雲泥の差で楽です。


今回はue10000はdragonflyの方を使うことにしました。paperclipdragonflyも機能的にほぼ優劣はなさそう。一番大きな違いはpaperclipはアップロード時に画像のリサイズを予めしておく感じ(自分でも同じように考えそう)、dragonflyは初回描画時に画像のリサイズをして、rack/cacheに画像を保存しておく感じ(なるほどそれもありだけど初回の負荷気になるよ)という部分のようです。


今回はデザイン部分が大幅に変わる可能性が高いので、dragonflyを使って画像アップロード機能を実装することにします。あとから画像のサイズ変わってアップロードしなおしとか嫌なんで。


初回描画時とrack/cacheを消した時の負荷が気になりますが、負荷が高いようであれば公開前にabや自前のクローラーでアクセスしておけばOKと割りきっていきます。逆にデザインが大きく変わることがない(しっかりデザインや使用用途が決まっていれば)のであればpaperclipのほうが使いやすそうです。このへんはケースバイケースかなと。チーム体制にもよりそうです。プログラム作る側がある程度デザインまでやってしまって、後からデザイン専門の担当者に修正してもらったりだったりすると、dragonflyのほうが楽かな?機能の追加もデザインの追加・変更もあることを考えると、dragonflyのほうが優秀な気がしてきました。paperclipだってアップロードしなおさなくても、DBの修正と画像サイズのリサイズスクリプトを作っておけば運用中に修正は効きます。dragonflyの方ならビューの簡単な修正(+スペック不足で表示が重くなるなら、事前アクセス)で対応できます。どっちが楽?と考えると、後者のビューの簡単な修正(+スペック不足で表示が重くなるなら、事前アクセス)のほうが楽な気がします。またrails使っていると、かなりの確率でcacheをはさんでいるはずなので。


というわけで実装してみます。


インストール自体は非常に簡単です。公式ドキュメント通りで動きます。

手順としては

OS側でimage-magickをインストール

sudo apt-get install libmagick++-dev imagemagick

Gemfileに以下を追記

gem 'rack-cache', :require => 'rack/cache'
gem 'dragonfly', '~>0.9.8'

bundle install

bundle install


起動時にdragonflyが使えるように config/initializers/dragonfly.rb を作成

require 'dragonfly/rails/images'

ここまででインストールは完了です。


では試しにphotoというscaffoldを作成して、動きを試してみます。

rails g scaffold photo
      invoke  active_record
      create    db/migrate/20111113014906_create_photos.rb
      create    app/models/photo.rb
      invoke    test_unit
      create      test/unit/photo_test.rb
      create      test/fixtures/photos.yml
       route  resources :photos
      invoke  scaffold_controller
      create    app/controllers/photos_controller.rb
      invoke    erb
      create      app/views/photos
      create      app/views/photos/index.html.erb
      create      app/views/photos/edit.html.erb
      create      app/views/photos/show.html.erb
      create      app/views/photos/new.html.erb
      create      app/views/photos/_form.html.erb
      invoke    test_unit
      create      test/functional/photos_controller_test.rb
      invoke    helper
      create      app/helpers/photos_helper.rb
      invoke      test_unit
      create        test/unit/helpers/photos_helper_test.rb
      invoke  stylesheets
   identical    public/stylesheets/scaffold.css


画像を扱うモデルを修正します。
ここで出てくる「image_accessor」がdragonflyが提供してくれるメソッドです。
今回は「image_accessor :photo_image」としています。
app/models/photo.rb

class Photo < ActiveRecord::Base
  image_accessor :photo_image
end


続いて実際にDBに値を保存するため、migrationを修正します。
"photo_image_uid"、"photo_image_name"というカラムを追加しています。
ごさっしの通り前述の「モデル側image_accessorで指定した名前+_uid」「モデル側image_accessorで指定した名前+_name」というカラムを作ります。
db/migrate/20111113014906_create_photos.rb

class CreatePhotos < ActiveRecord::Migration
  def self.up
    create_table :photos do |t|
      t.string "photo_image_uid"
      t.string "photo_image_name"
      t.timestamps
    end
  end

  def self.down
    drop_table :photos
  end
end


DBに反映したいのでココらへんでrake db:migrateしてください。


ビューを修正します。アップロード時のフォームを修正。
以下を追加しています。詳細は以下のソース見てね。
「:html => {:multipart => true}」「<%= f.file_field :photo_image %>」

app/views/photos/_form.html.erb

<%= form_for(@photo, :html => {:multipart => true}) do |f| %>
  <% if @photo.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@photo.errors.count, "error") %> prohibited this photo from being saved:</h2>

      <ul>
      <% @photo.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <%= f.file_field :photo_image %>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>


ここまでで画像のアップロードが動きます。
http://localhost:3000/photos/newとかにアクセスして試してみてください。


次に表示。ここはdragonflyの真骨頂と思える部分。

「モデル名.image_accessorで指定した名前.url」で画像が入ったURL文字列を取得
「モデル名.image_accessorで指定した名前.thumb(リサイズサイズ指定).url」でリサイズされた画像が入ったURL文字列を取得
等々ができます。jpg取得もtiff変換も可能です。

app/views/photos/index.html.erb

<h1>Listing photos</h1>


<% @photos.each do |photo| %>

<%= image_tag photo.photo_image.url %>
<%= image_tag photo.photo_image.thumb('400x200#').url %>
<%= image_tag photo.photo_image.jpg.url %>
<%= image_tag photo.photo_image.process(:greyscale).encode(:tiff).url %>

<%= link_to 'Show', photo %>
<%= link_to 'Edit', edit_photo_path(photo) %>
<%= link_to 'Destroy', photo, :confirm => 'Are you sure?', :method => :delete %>


<% end %>


<br />

<%= link_to 'New Photo', new_photo_path %>

http://localhost:3000/photos
で動きを確認することができるはず。


後でスコア撮ってみますが、初回描画時はやっぱ体感レベルで重いな(^_^;)
二回目以降はキャッシュから読み出しているので問題なく早いです。


ちなみに画像のアップロード先フォルダは
public/system/dragonfly/環境名(production,test,development)/日付/ファイル名

となっているようです。



ちなみにdestroy actionもscaffoldのコードで動いちゃいます(これは素直に感心した)。実態の画像ファイルも消してくれます。

CoffeeScript-mode.el install

ついでにemacs用の環境もインストール。

$ cd ~/src
$ mkdir coffee-script
$ cd coffee-script
$ git clone git://github.com/defunkt/coffee-mode.git
Cloning into coffee-mode...
remote: Counting objects: 445, done.
remote: Compressing objects: 100% (296/296), done.
remote: Total 445 (delta 157), reused 423 (delta 144)
Receiving objects: 100% (445/445), 66.73 KiB, done.
Resolving deltas: 100% (157/157), done.
$ mv coffee-mode/coffee-mode.el ~/.emacs.d


あとは.emacsに以下を追記

;; coffee-script mode
(require 'coffee-mode)
(add-to-list 'auto-mode-alist '("\\.coffee$" . coffee-mode))
(add-to-list 'auto-mode-alist '("Cakefile" . coffee-mode))


快適快適!

CoffeeScript Install Memo

CoffeeScriptのインストールメモ


こんばんはこんばんはue10000です。


以前開発環境ごとぶっ飛ばしたせいでCoffeeScriptを触ろうと思ったら、node.js入ってなくね・・・な状況になっていました。
しかしnode.jsは昔に比べてインストールも非常に楽になっていました。


比べる対象は違いますが、
WindowsUpdateとかくそじゃね?と思えるほど最近のLinuxは便利です。

続きを読む

node.js + expressを試す

こんばんはこんばんはue10000です。
改馬・・・・おっと。みなさんブラウザ三国志やりませんか?yahooモバゲ1鯖にいます。今日から2期目が始まります。一日一回しかログイン出来ないので非常に弱っちいですが。きんぐ☆アーサー同盟にいます。


最近Pythonを触る機会が減ってます。LLでGAE触りたくてPython覚えて、非常に良い言語なんですが、あちこちに浮気してます。サーバー・ネットワークまで自分で触りたいue10000としてはクラウド環境含めて自分で触りたくなってしまって。となると自分と雰囲気が合わないPythonジャなくてRubyJavaで触りたくなってしまう。。。悪い癖です。というわけで今日はnode.jsを触ってみます。今日はサーバー起動までやってみます。

続きを読む

MacBook Air 11インチ欲しい!

MacBook Air 11インチ欲しい!
キャンペーンに応募したいので書きます。

ずーとMacがほしいのですが、なかなか手が出せてません。
これを機会に手に入ることがあったら・・・・・


iphoneアプリの開発に手を出します。
間違いなく。


何を作るのかは未定ですが・・・AR系の位置情報連携RPGでバッサバッサ街の中でモンスターを倒すなんてどうでしょうw

Rails製ECサイト構築パッケージSpree

コンバンハコンバンハue10000です。


Blogの題名ではPython・・・・ォイ
ですがRailsのが好きだったりしますww


というわけで、活発に開発が進められているSpreeについての導入メモ。ECサイトと言えばPHPosCommerce・ECCube等が有名ですが、Ruby on Rails制のECサイト制作に役立つパッケージを触ってみました。

続きを読む

/etc/profileや/etc/bashrcをぐちゃぐちゃにしてしまいSSHでログインできなくなったとき

今日2回目のコンバンハこんばんは。ue10000です。個人的な備忘録。


表題の通りなんですが、/etc/profileや/etc/bashrcや$HOME/.bashrc等にありえない事を書いてしまうと、SSHでログインできなくなります。

続きを読む