| Path: | README_JA |
| Last Update: | Thu May 22 15:59:09 +0900 2008 |
image_upload は、スマートな Ajax U/Iで画像をアップロードできる機能を簡単に追加するための Ruby on Rails プラグインです。 次のような特徴があります。
このプラグインは、Rails 1.2.6, Rails 2.0.2, IE7.0(Windows), IE6.0(Windows), FireFox(Windows, MacOSX), Safari(MaxOSX) でテストされています。
プラグインの使用例として、image_exmaples アプリケーションがありますので参考にしてください。
以下のコマンドによってチェックアウトすることができます
svn checkout http://imageupload.rubyforge.org/svn/trunk/image_examples
または
svn checkout svn://rubyforge.org/var/svn/imageupload/trunk/image_examples
なお、image_examples を動かすには GetText が必要です。 GetText は以下のようにしてインストールしてください。
> gem install gettext
image_upload プラグインを使うには、以下のような手順が必要です。
image_upload プラグインは以下のコマンドでインストールできます。
> ruby script/plugin install http://imageupload.rubyforge.org/svn/trunk/image_upload/
image_upload プラグインを使うには、responds_to_parent プラグインが必要です。 以下のようにしてアプリケーション内にインストールします。
ruby script/plugin install http://sean.treadway.info/svn/plugins/responds_to_parent/
注意:最近上記のレポジトリから取得できない状況のようです。image_examples アプリケーション内ものをコピーして使うという方法があります。
例)
> ruby script/plugin install http://imageupload.rubyforge.org/svn/trunk/image_examples/vendor/plugins/responds_to_parent
> ruby script/plugin install acts_as_list
image_upload では、画像をモデルとして扱います。モデルクラスを生成するには、
./script/generate image_upload stored_file
を実行します。stored_file の代わりに任意の画像ファイルクラス名を指定できます。
画像イメージクラスには単一テーブル継承を利用することもできます。 生成した stored_file モデルをそのまま利用せず、画像種類ごとにクラスを作るといった利用方法が考えられます。派生クラスの記述例は以下のようになります。
class EntryImage < StoredFile end
ImageUpload では、オリジナルの画像ファイル名を表示に利用せず、ランダムな名前をつけて表示します。この機能を使わない場合は、generator でモデルを作る際に use_original_name を指定します。
./script/generate image_upload stored_file use_original_name
generator で作られた画像モデルは、Polymorphic 関連で親モデルに紐づけられるようになっています。特定の親モデル専用の画像モデルを作るので Polymorphic である必要がない場合は、generator でモデルを作る際、親モデル名を指定します。例えば article が親なら以下のようにします。
./script/generate image_upload stored_file article
より細かい指定が必要なとき(クラス名や外部キーの命名ルールが異なるとき)は、生成されたモデルクラスの belongs_to 指定を書き換えてください。
また、親モデル側で image_attached を使う際に、:polymorphic => false を指定します。
image_attached :polymorphic => false
generator で生成された画像モデルクラスの path メソッドを変更、または派生クラスでオーバーライトします。生成時点では以下のように、public/images 以下に モデルクラスの複数名のサブフォルダを切って格納されるようになっています。
# You can overwrite this.
def path
"#{RAILS_ROOT}/public/images/#{self.class.to_s.underscore.pluralize}"
end
ここには、public/images 以下でない自由なパスを指定することができます。public/images 以下でないパスに画像を格納すると、画像へのアクセス管理をアプリケーションを通じて行うことができます。
なお、public/images 以下のパスでない場合、以下を指定することが必要ですので注意してください。
画像をつけたいActiveRecordモデルを決め、image_attached を指定します。
例えば、UserProfile というモデルに画像を1つ関連づける場合のコードは以下のようになります。
class UserProfile < ActiveRecord::Base
image_attached
end
image_attached には以下のオプションを渡すことができます。
例えば、Entry クラスに画像を最大3つつけるようにし、モデルクラス名が EntryImage である場合は以下のように指定します。
image_attached :size => 3, :class_name => 'EntryImage'
1つの親モデルに対して複数種類の関連を指定することができます。 次の例では、User モデルにプロフィール画像と家の写真を関連づけます。
class User < ActiveRecord::Base image_attached :name => :profile_image, :class_name => 'ProfileImage', :polymorphic => false image_attached :name => :house_image, :class_name => 'HouseImage' end
親モデルから画像モデルへは、has_one または has_many の関連がはられます。 実際の関連名は、image_attached の :name オプションの先頭に’stored_’をつけたものとなりますが、参照には疑似関連名を使ってください。 例えば、疑似関連名が :images なら、parent.images でイメージモデルの配列を得られます。:image なら、parent.image でイメージモデルまたは nil が得られます。
一般的には、stored_xxx の関連に関しては画像アップロードプラグインが処理するので、開発者が気にする必要はありません。
画像をつけたモデルの編集を行うコントローラに、以下の変更を加えます。
例えば UserProfileController の実装例は以下になります。
class UserProfileController < ApplicationController
image_upload 'User', :starts_at => [:new, :edit] # 1
def new
@profile = UserProfile.new
end
def edit
@profile = UserProfile.find(params[:id])
end
def update
@profile = UserProfile.find(params[:id])
@profile.attributes = params[:user_profile]
set_images_to(@profile) # 2
if @profile.save
clear_session_images # 3
redirect_to :action => 'index'
else
render :action => 'edit'
end
end
end
image_upload の最初の引数には、このコントローラでアップロードされる画像をつけるモデルのクラス名を指定します。 二番目の引数にはオプションを指定します。オプションには、以下を指定できます。なお、通常の利用方法においては、:starts_at を最低1つ指定することになるでしょう。
なお、1つのコントローラでは、image_upload は1回しか呼び出せません。つまり、1つのコントローラでは一種類の親モデルに関するアップロードしか行えません。
image_upload を記述すると、コントローラに以下のアクションが自動的に追加されます。自前のフィルターを記述する場合は、これらのアクションにそのフィルターを適用するかどうかを判断する必要があります。
注意: session_image はイメージのバイナリを出力します。もしテキストコンテンツ向けに、HTTPレスポンスヘッダを変える after filter などを用意している場合、 このメソッドを Skip 指定するのを忘れないようにしてください。
組み込みのファイル種類チェック以外のチェックを行いたい場合は、コントローラに、protected で validate_image(path) を実装します。validate_image では、エラーがあった場合に、@image_errors にエラーメッセージを追加してください。例えば、サイズ制限をする場合の例は以下のようになります。
protected
def validate_image(path)
if File.size(path) > 512.kilobytes
@image_errors << 'The image file should not be larger than 512KB.'
end
end
アップロードフィールドは以下のように記述します。
<%= image_upload_field(@profile, :width => 80, :height => 60, :form_id => 'myform') %>
最初の引数には、画像をつけたいオブジェクトを指定します。 オプションには以下を指定できます。
また、画像をpublic/images 以下に配置しない場合は、DB保存済の画像をアップロード作業中に表示するためのurlを、ブロックで指定する必要があります。
例)
<%= image_upload_field(@entry) {|f|
url_for(:controller => 'entries',
:action => 'image',
:unique_key => file.unique_key,
:ext => file.ext)} %>
アップロードフィールドの記述にあたっては、以下の環境条件を満たす必要があります。
保存済みの画像の表示を支援するヘルパーメソッド stored_image_tag を用意しています。 public 以下に保存する場合も、そうでない場合も利用できます。
例)public 以下に保存しない場合
<%= stored_image_tag image, :action => 'image', :id => entry.id, :unique_key => image.unique_key, :ext => image.ext %>
例)public 以下に保存する場合
<%= stored_image_tag image %>
stored_image_tagの引数は以下のようになっています。
def stored_image_tag(image, url_options = {}, html_options = {}, default_image = nil)
ImageUploadプラグインを入れると、すべてのController からsend_stored_file メソッドを使うことができるようになります。これを利用して簡単に画像ファイルをHTTPレスポンスとして送り出せます。
# You can add access controll feature here.
def image
entry = Entry.find(params[:id])
image = entry.images.detect{|i| i.unique_key == params[:unique_key]}
send_stored_file(image)
end
画像を一時的に保存するフォルダ内の画像は、アップロード処理をユーザーが途中で放棄すると、削除されないまま残ります。このようなごみは、定期的に削除する必要があります。
generator で生成した画像モデルは、Ajaxを使わないアップロードにも対応しています。
Ajaxを使わないアップロードでこれらのモデルを利用するには、buffer= でアップロードされたバッファを格納してからsaveするようにします。
例えば、viewで以下のように記述し、
<%= file_field(:message, :attached_file_buffer) %>
Mesasge クラスに以下のように記述します。
class Message
attr_accessor :attached_file_buffer
protected
def before_create
f = build_attached_file
f.buffer = attached_file_buffer
end
end
routes.rbに追加されたmap.resourcesに下記のようにcollectionを追記してください。
map.resources :users, :collection => { :session_image=>:get, :upload_session_image=>:put }
または、map.resourcesより前に下記のようにmap.connectを追記しても動作します。
map.connect 'users/:action/:id', :controller => 'users', :action => /session_image|upload_session_image/
バグレポートやフィードバックは歓迎です。tlab@support.email.ne.jp までお送り下さい。