7 : 画像のアップロード

前の章 : チャットルームの作成④

Coffeecup header7

0 : この章の目的

 前章までで、チャットルームの作成をした。

この章では、ユーザー情報に画像を加え画像を表示させる。


 Windowsをご利用の方は、機種の関係でこの章の内容を学ぶことはできません。
 ご了承の上、次の章に進んで下さい。



 具体的な流れを説明しましょう!

 まずは変更するユーザー情報を記入するページ、users」データベースの「edit」ページChrome messages users 1 edit no image のような ファイルを選択する入力欄を設定します。

ファイルを選択して 登録する をクリックすると、 Chrome messages users 1 edit upload image のようにアップロードした画像が表示されます。

アップロードした画像は、 Chrome messages users 1 after upload images Chrome messages rooms 1 messages with images のように別のページでも表示させます。
  具体的には、「paperclip」という「gem」を使って、画像のアップロードをします。

ではやってみましょう!

 画像は、河出書房新社様の『トーニオ・クレーガー』(トーマス・マン著・平野卿子訳)の表紙からいただきました。河出書房新社様、ありがとうございました。


1 : Paperclipを導入する

まずは「Paperclip」を導入してみましょう!
Paperclipを導入する前に、
これを使うためのimageMagickというツールをインストールします。

ターミナルで下の入力をして下さい。

 ターミナル
1 brew install imagemagick

これでimageMagickを導入することができました!
※ これでインストールできたので、今後この入力をする必要はありません
では、Paperclipをインストールしましょう!

Sublime Textを開いて、Gemfileに下の内容を加えて下さい。
※ Sublime Textの開き方はこちらを参考にして下さい

 Gemfile
※ 半角英数字で入力。変更が完了したら「Command」と「s」を一緒に押して内容を保存して下さい。
32 gem 'paperclip'

大体、32行目らへんに追加します。
これが終わったら設定を導入します。ターミナルで下の入力をして下さい

 ターミナル
1 bundle install

 動かない場合は、「Gemfile.lock」を削除してから、試してみて下さい。

  これで「Paperclip」の導入ができました!

この「Paperclip」を使って、画像のアップロードをしてみましょう!


2 : 画像をアップロードする

Paperclip」を使って、画像のアップロードをしましょう!

 ① : 画像アップロードの仕組み


この章ではPaperclipを使って画像のアップロードをしていきますが、これはどのような仕組みになっているのでしょうか?

 大体の流れをもう一度確認しましょう。

  まず「users」データベースの「edit」ページを開いて、 Chrome messages users 1 edit no image 画像の入力欄を開いて画像を選択して、 Chrome messages users 1 edit select images 登録する をクリックすると、 Chrome messages users 1 edit upload image のように画像が保存されて表示されます。
 ではこの保存した画像はどこにあるのでしょうか?

これらの画像は、public > systemに保存されます。 Sublime text public system images ここに保存された画像をページで表示させています。
 次に、保存した画像の表示の方法について説明します。

画像と会員の紐付けをするために、users」データベース画像名を入れる枠組みを追加して、

users
image_file_name image_content_type image_file_size image_updated_at
トーニオ・クレーガー.jpg image/jpeg 164788 2016-04-25 04:45:48
この枠組みのデータを使って、画像の表示をしています。

 例えば、「id」が「1」の会員であれば Sublime text public system public > system > users > images > 000 > 000 > 001 > medium > 画像名の画像を表示させます。

追加した「image_file_name」の枠組みの内容を、上にある画像名に入れて画像を表示させています。

 途中に「medium」というフォルダがありますが、これは画像の大きさになります。

画像の大きさは
  • original(元の大きさ)
  • medium(中)
  • thumb(小)
の3つがあり、それぞれのフォルダに画像ファイルが保存されます。
これらの大きさは自分で決めるので、後で設定してみましょう!

 では実際に「Paperclip」を使ってみましょう!


 ② : 「Paperclip」を使う


このような流れでPaperclipは画像のアップロードをしていました。
実際のPaperclipで設定することは、
  • データベースにへの枠組みの追加
  • users
    image_file_name image_content_type image_file_size image_updated_at
    トーニオ・クレーガー.jpg image/jpeg 164788 2016-04-25 04:45:48
  • データ操作の設定
  • 画像を保存して、上のデータベースの枠組みに変更を加える設定をします。

  • ページ表示の設定
  • ページに画像を表示させる設定をします。

の3つになります。

 ではやってみましょう!

 ⑴ : データベースの変更


 まずは、データベースに画像の枠組みを加えます。

画像のデータベースの枠組みを追加するには、ターミナルで

 ターミナル
1 rails g paperclip user image

を入力します。
これでusers」データベースに「image」の枠組みを追加する設定ファイル「日時_add_attachment_image_to_users.rbを作成しました。
※ 「image」の枠組みは、「photo」のように好きな名前にもできます。
作成された設定ファイルの内容を確認します。
db > migrate > 日時_add_attachment_image_to_users.rbを開いて、内容を確認しましょう!

 日時_add_attachment_image_to_users.rb
1 2 3 4 5 6 7 8 9 10 11 class AddAttachmentImageToUsers < ActiveRecord::Migration def self.up change_table :users do |t| t.attachment :image end end def self.down remove_attachment :users, :image end end

この設定ファイルを適用させるためにターミナルで、

 ターミナル
1 rake db:migrate

を入力しましょう!
 動かない場合は、「bundle exec」を前につけ、「bundle exec rake ...」で入力して下さい。

これでデータベースの設定を適用できました!
Sequel Proでデータベースができているかを確認しましょう!
※ Sequel Proの開き方はこちらを参考

「created_at」「updated_at」の後ろに、
image」の枠組みが追加されているのを確認できたでしょうか? Sequel pro images


 ⑵ : データ操作


 次に、データ操作をします。

データ操作には
  • 「image」の枠組みの変更を可能にする(users_controller.rb)
  • 「image」の大きさ、ファイルの設定(user.rb)
の2つを設定します。

 まずは「users_controller.rb」の変更からやってみます。

画像のアップロードは、users」データベースの「edit」ページで選択した画像を Chrome messages users 1 edit no image update」ページでアップロードします。
ここではupdate」で「image」データベースの変更も可能にする設定をします。

app > controllers > users_controller.rbを開いて、内容を下のように変更してみましょう!

 users_controller.rb(31行目を変更)
※ 半角英数字で入力。変更が完了したら「Command」と「s」を一緒に押して内容を保存して下さい。
28 29 30 31 32 33 34 35 36 37 38 def update @user = User.find(params[:id]) if @user.id == current_user.id @user.update(params.require(:user).permit(:first_name, :family_name, :self_introduction, :age, :image)) redirect_to "/users/#{@user.id}/edit" flash[:notice] = "編集が完了しました" else redirect_to "/" flash[:alert] = "無効なユーザー" end end

31行目の後ろで

1 permit( ... , :age, :image)

のように設定して、imageの変更を可能にしています。
 次に「user.rb」に設定を加えます。

「Paperclip」を使うにはuser.rb
  • 画像の大きさの設定
  • 画像のファイルの設定
の2つをやります。

 一つ目「画像の大きさの設定」からやってみます。

Paperclipでは、「css」で使ったpx単位でアップロードする画像の大きさを設定できます。

ここでは、
  • 縦300/横300
  • 縦50/横50
の2つの大きさを設定します。

ではapp > models > user.rbの内容を下のように変更しましょう!

 user.rb(10行目を追加)
※ 半角英数字で入力。変更が完了したら「Command」と「s」を一緒に押して内容を保存して下さい。
1 2 3 4 5 6 7 8 9 10 11 12 class User < ActiveRecord::Base # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable has_many :messages has_many :entries has_attached_file :image, styles: { medium: "300x300>", thumb: "50x50>" } end

これで300x300」「50x50の大きさの画像を保存する設定ができました。
 次は二つ目「画像ファイルの設定」をやります。

ここでは保存できるファイルの種類を設定します。

例えば画像を保存するのに、音楽を再生するためのmp4」ファイルを保存しても仕方ないですよね。

ここでは、
  • jpg
  • jpeg
  • png
  • gif
の4つのファイルを保存できるようにします。

ではapp > models > user.rbの内容を下のように変更しましょう!

 user.rb(12行目を追加)
※ 半角英数字で入力。変更が完了したら「Command」と「s」を一緒に押して内容を保存して下さい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class User < ActiveRecord::Base # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable has_many :messages has_many :entries has_attached_file :image, styles: { medium: "300x300>", thumb: "50x50>" } validates_attachment :image, content_type: { content_type: ["image/jpg", "image/jpeg", "image/png", "image/gif"] } end

ここで、設定したjpg」「jpeg」「png」「gifファイル以外は保存できないようにしました。

  ここまででデータ操作の設定が完了しました。


 ⑶ : ページ表示


 次にページ表示をやってみましょう!

ページ表示には
  • 入力欄の設定
  • Chrome messages users 1 edit no images no message
  • 画像の表示

  •  大きさ「medium」の画像(300x300)の表示 Chrome messages users 1 after upload images  大きさ「thumb」の画像(50x50)の表示 Chrome messages rooms 1 messages with images
の2つがあります。

 まずは入力欄の設定をしてみます。

会員情報を編集するページ、users」データベースの「edit」ページにファイルの入力欄を追加します。 ではapp > views > users > edit.html.erbの内容を下のように変更しましょう!

 edit.html.erb(4〜6行目を追加)
※ 半角英数字で入力。変更が完了したら「Command」と「s」を一緒に押して内容を保存して下さい。
1 2 3 4 5 6 7 ... <h1>ユーザー情報を編集する</h1> <hr> <%= form_for @user do |f| %> <p>プロフィール画像</p> <%= f.file_field :image, :class => "form-control my-form" %> <br> <p>名字</p> <!-- 省略 -->

これでファイルの入力欄を設定できました。

このようにファイルの入力欄は、

6 <%= f.file_field :image, :class => "form-control my-form" %>

のように「file_field」を使って設定します。
ここでもform-controlを使って入力欄を装飾しています。
 入力欄の設定とデータ操作ができたので、一度画像を保存してみましょう!

まずは会員でログインして、会員の情報編集ページに移動しましょう!
※ 一回「rails s」で動かしたサーバーを「Control」と「c」を一緒に押して止めてから、もう一度「rails s」を入力して下さい。 Chrome messages users 1 edit no images no message このようなページは出てきたでしょうか?
ページが出てきたら、画像の入力欄をクリックし画像を選択して、 Chrome messages users 1 edit select images 登録する をクリックしましょう!

これで画像は保存されたので、
まずはpublic > system以下に画像があるかを確認しましょう! Sublime text public system images ついでに、Sequel Proにデータが保存されたかを確認しましょう! Sequel pro images user 1
 次に画像の表示をします。

今度は保存した画像を表示してみます。

 まずはmedium」(縦300横300)の画像を
  • users」データベースの「show」ページ
  • Chrome messages users 1 after upload images
  • users」データベースの「edit」ページ
  • Chrome messages users 1 edit upload image
に表示させましょう!
まずは、app > views > users > show.html.erbの内容を下のように変更して下さい。

 show.html.erb(5、6行目を追加)
※ 半角英数字で入力。変更が完了したら「Command」と「s」を一緒に押して内容を保存して下さい。
1 2 3 4 5 6 7 8 9 10 ... <div class="row"> <div class="col-xs-6"> <h1>ユーザー情報</h1> <hr> <%= image_tag @user.image.url(:medium) %> <br><br> <p>名前:<%= @user.family_name %><%= @user.first_name %>さん(<%= @user.age %>歳)</p> <p>自己紹介:<%= @user.self_introduction %></p> <br> <% if @user.id == current_user.id %> <!-- 省略 -->

中にある

6 <%= image_tag @user.image.url(:medium) %>

で画像の表示をしています。

@userで会員のデータの選択をし、
その会員データに対応する「大きさ medium」の「imageを表示させています。
※ 後ろに「<br>」を2つつけて、画像と名前の間に隙間を入れています Chrome messages users 1 after upload images
同じようにしてusers」データベースの「edit」ページに画像を表示させてみます。

app > views > users > edit.html.erbの内容を下のように変更しましょう!

 edit.html.erb(5、6行目を追加)
※ 半角英数字で入力。変更が完了したら「Command」と「s」を一緒に押して内容を保存して下さい。
1 2 3 4 5 6 7 8 9 10 <h1>ユーザー情報を編集する</h1> <hr> <%= form_for @user do |f| %> <p>プロフィール画像</p> <%= image_tag @user.image.url(:medium) %> <br><br> <%= f.file_field :image, :class => "form-control my-form" %> <br> <p>名字</p> <!-- 省略 -->

5行目の設定で、上と同じように画像の表示をします。 Chrome messages users 1 edit upload image
 次にthumb」(縦50横50)の画像を
  • rooms」データベースの「show」ページ
  • Chrome messages rooms 1 messages with images
に表示させましょう。

thumbの大きさの画像は、

1 <%= image_tag @user.image.url(:thumb) %>

のように設定して表示させます。
ではapp > views > rooms > show.html.erbの内容を下のように変更しましょう!

 show.html.erb(22、30行目を変更)
※ 半角英数字で入力。変更が完了したら「Command」と「s」を一緒に押して内容を保存して下さい。
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 ... <div class="col-xs-9"> <% if @messages.present? %> <% @messages.each do |m| %> <% if m.user_id == current_user.id %> <h4 class="text-right"> <p class="alert alert-success"> <%= m.content %> <br><br> <small><strong><a href="/users/<%= m.user_id %>"><%= m.user.family_name %> <%= m.user.first_name %>さん <%= image_tag m.user.image.url(:thumb) %></a></strong></small> </p> </h4> <% else %> <h4 class="text-left"> <p class="alert alert-info"> <%= m.content %> <br><br> <small><strong><a href="/users/<%= m.user_id %>"><%= image_tag m.user.image.url(:thumb) %> <%= m.user.family_name %> <%= m.user.first_name %>さん</a></strong></small> </p> </h4> <% end %> <% end %> <% else %> <!-- 省略 -->

22、30行目のそれぞれ名前を表示させている部分の前/後ろに、

1 <%= image_tag m.user.image.url(:thumb) %>

を設定して、会員の画像を表示させています。
※ m.usermessages」データベースを持っている会員を選択しています。 Chrome messages rooms 1 messages with images  ここまでで画像を表示させることができました!


 ③ : まとめ


Paperclipの使いかたをまとめる。
  • データベースの追加

  • データベースを追加するための設定ファイルを作成します。

     ターミナル
    1 rails g paperclip user image

    今回は、users」データベースに「image」の枠組みを加えるための入力になります。

    この入力で「日時_add_attachment_image_to_users.rb」ファイルが作成されます。

    これが終わったら設定を適用させます。

     ターミナル
    1 rake db:migrate

  • データ操作

  • データ操作には、
    • users_controller.rb
    • user.rb
    の2つのファイルに設定を追加します。

     users_controller.rb
    1 @user.update(params.require(:user).permit(:first_name, :family_name, :self_introduction, :age, :image))

     user.rb
    1 2 has_attached_file :image, styles: { medium: "300x300>", thumb: "50x50>" } validates_attachment :image, content_type: { content_type: ["image/jpg", "image/jpeg", "image/png", "image/gif"] }

  • ページ表示

  • ページ表示には、
    • 入力欄の表示
    • 画像の表示
    の2つをやります。

     入力欄の表示

    1 <%= f.file_field :image, :class => "form-control my-form" %>

     画像の表示

    1 <%= image_tag @user.image.url(:medium) %>

  Paperclip」を使った画像の表示はここまでです。

今度は条件分岐を使って、会員の画像がない場合は Chrome messages users 2 no image Chrome messages users 1 edit no image のように画像の代わりに、
画像はありません」「画像はまだ登録されていません」を表示させてみましょう!


3 : 画像の判別

条件分岐を使って、画像の表示・非表示を設定してみましょう!
会員の画像があるかないかの判別は、前に説明したpresent?で判別します。
※ 詳細はこちらを参考にして下さい

なので大体このように設定します。

1 2 3 4 5 <% if @user.image.present? %> <%= image_tag @user.image.url(:medium) %> <% else %> <h4>画像はありません</h4> <% end %>

では
  • users」データベースの「show」ページ
  • Chrome messages users 2 no image
  • users」データベースの「edit」ページ
  • Chrome messages users 1 edit no image
の2つで設定を加えてみます。

 まずは「users」データベースの「show」ページに設定を加えます。

app > views > users > show.html.erbの内容を下のように変更して下さい。

 show.html.erb(5、8〜10行目を追加)
※ 半角英数字で入力。変更が完了したら「Command」と「s」を一緒に押して内容を保存して下さい。
1 2 3 4 5 6 7 8 9 10 11 12 ... <div class="row"> <div class="col-xs-6"> <h1>ユーザー情報</h1> <hr> <% if @user.image.present? %> <%= image_tag @user.image.url(:medium) %> <br><br> <% else %> <h4>画像はありません</h4> <% end %> <p>名前:<%= @user.family_name %><%= @user.first_name %>さん(<%= @user.age %>歳)</p> <p>自己紹介:<%= @user.self_introduction %></p> <!-- 省略 -->

これで@user」の「image」がある場合とない場合での判別ができました。
 次に「users」データベースの「edit」ページに設定を加えます。

app > views > users > edit.html.erbの内容を下のように変更して下さい。

 edit.html.erb(5、8〜10行目を追加)
※ 半角英数字で入力。変更が完了したら「Command」と「s」を一緒に押して内容を保存して下さい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <h1>ユーザー情報を編集する</h1> <hr> <%= form_for @user do |f| %> <p>プロフィール画像</p> <% if @user.image.present? %> <%= image_tag @user.image.url(:medium) %> <br><br> <% else %> <h4>画像はまだ登録されていません</h4> <% end %> <%= f.file_field :image, :class => "form-control my-form" %> <br> <p>名字</p> <!-- 省略 -->

ここまで条件分岐の設定が完了しました。

 Paperclip」を使った画像のアップロードは以上になります。

設定した内容はこちらにまとめてあります。

 こちらからウェブサイトの公開方法を学べます。ご参考にして下さい。


 ここまでで「応用編」も終了です。お疲れさまでした。

もっとこの「Ruby on Rails」に興味がある人向けに、勉強できるサイト・本・塾の紹介をしますので良かったら見てみて下さい。