画像を保存して表示する方法
imageカラムを用意する。 string型でよい。
$ rails g migration add_image_to_users image:string
以下のコードでも可能。
$ rails g migration AddImageToUsers image:string ```` データベースに反映させる。
$ rake db:migrate
アプリケーション側で用意しておく画像は`app/assets/image`に保存しておくが、ユーザーがアップロードする画像は`public`フォルダに保存する。 今回は、publicフォルダ内にuser_imagesというフォルダを作成する。 このフォルダには画像データそのものが保存される。
publicフォルダにuser_images
フォルダを作成する。
viewにフォームを記述する。 画像をアップロードするには`file_field`ヘルパーを用いる。 `file_field`は`type="file"`の`input`タグを生成するので、ユーザーが画像を選択し、アップロードできるようになる。 第一引数に属性`:name`を記述する。
プロフィール画像 <%= f.file_field :image, %>
画像を保存するためのコード。 original_filenameはrailsに定義されているメソッド。 user_controller.rb
def create @user = User.new(user_params) file = params[:user][:image]
画像ファイルの取得
if !file.nil?
受け取った画像データが空ではない場合
file_name = file.original_filename
画像名の取得
File.open("public/user_images/#{file_name}", 'wb')
画像データの保存先とファイル名(画像名)の指定
'wb'は画像データを書き込む場合
{|f| f.write(file.read)}
画像データの書き込み
@user.image = file_name
セッターを用いて画像名のセット
end if @user.save
保存
. . .
controllerにこのまま記述してもよいが、modelにリファクタリングするのが通例。 モデルに`set_image`メソッドとして定義する。 models/user.rb
class User < ActiveRecord::Base def set_image(file) if !file.nil? file_name = file.original_filename File.open("public/user_images/#{file_name}", 'wb') {|f| f.write(file.read)} selg.image = file_name end end end
モデルで定義したインスタンスメソッドはコントローラやビューファイルで`インスタンス.メソッド名`で自由に呼び出すことができる。 インスタンスメソッド内の`self`は呼び出し元のインスタンスを指す。
def create @user = User.new(user_params) @user.set_image(file)
インスタンスメソッドの呼び出し
end
def update @user.set_image(file)
インスタンスメソッドの呼び出し
user.rb
def set_image(file) if !file.nil . . . self.image = file_name
呼出し元のインスタンス
end
今回はプロフィール画像を登録している場合にはその画像を、登録していない場合は、デフォルト画像を表示するように設定する。
<%= @users.each do |user| %> <% if @user.image %> <%= image_tag "user_images/#{user.image}" %> <% else %> <%= image_tag "hoge.png %>
デフォルト画像の表示
<% end %> <% end %>
publicフォルダの中の画像を表示する場合
image_tag "/user_images/#{user.image}"
app/assets/imagesの中の画像を表示する場合
ヘルパーを定義してリファクタリングを行う。 `image_tag "user_images/#{user.image} or `image_tag "hoge.png" どちらかが戻り値 users_helper.rb
module UsersHelper def image_for(user) if user.image image_tag "/user_images/#{user.image}" else image_tag "hoge.png" end end end
ヘルパーの呼び出し方
<%= image_for(user) %>
<%= image_for(@user) %>