Ruby / Rails

写真投稿機能の追加

2019年7月7日

こんにちは、Nanayakuです。

今回は、画像投稿機能の追加について解説していきます。

目次

画像の保存方法

画像はデータベースに直接保存しません

画像はデータの容量が多いため、データベースの容量を圧迫し、データ形式の変換など扱いが難しいからです。

そのため、画像は違うところに保存し、画像の保存場所(パスやURL)の文字列をデータベースに保存します。

 

Topicモデルについて

これは上記でも説明した通り、写真のリストのデータベースを作成するモデルです。

モデルの概要は以下の通りです。

カラム
user_id(ユーザーのid ) integer
description(画像の概要/説明 ) string
image(画像のパス/名前) string

ここで、UserテーブルとTopicテーブルを関連づけるため、外部キーが必要になります。

今回は「user_id」が外部キーになります。

外部キーとは、「他のテーブルの主キーを保存するためのカラム」の事です。

これにより、自分が投稿した写真を編集したり、自分が投稿した写真の一覧を見るなどの操作が簡単に出来ます。

 

Topicモデルの作成

以下のコマンドで、上記の概要通りのテーブルが出来ます。

rails g model Topic user_id:integer description:string image:string

rails db:migrateのコマンドで、データベースに適用させます。

空欄で投稿できないようにバリデーションを各カラムに追加します。

 

関連付け(アソシエーション)

Userから見たTopicの関係とTopicから見たUserの関係を明示的に表現することで、全削除などの操作の設定が簡単になります。

「それぞれのtopicは1つのuserを持つ」と言うTopicから見たUserの関連付けは「belongs_to」で出来ます。

Railsドキュメント・belongs_to

 

「1つのuserは複数のtopicを持つ」と言うUserから見たTopicの関連付けは「has_many」で出来ます。

【Rails入門説明書】has_manyについて解説

このように関連付けをすることで、Railsは参照先をデータを簡単に取得・編集・削除できるメソッドを追加してくれます。

 

画像投稿機能の作成

Railsには、「CarrierWave」と言うgemがあります。

このgemは、画像のアップロード機能を簡単に追加・実装できます。

Gemfileに「gem "carrierwave"」を追記し、bundle installでインストールします。

公式サイト(CarrierWave)

 

画像アップロードファイルの作成

「rails g uploader image」コマンドでアップロードファイルを作成します。

アップロードファイルとモデルを紐づけるため、以下のコードを「app/models/topic.rb」に書きます。

mount_uploader :carrierwave用に作ったカラム名, carrierwaveの設定ファイルのクラス名

mount_uploader :image, ImagesUploader

railsでcarrierwaveを使って画像をアップロード、表示

エラーが出ないように「config/application.rb」へ以下のコードを追記します。

config.autoload_paths += Dir[Rails.root.join('app', 'uploaders')]

 

ルーターの設定

resources :topicsでまとめて設定します。

 

Controller・Viewの作成

コントローラーの設定と同じように、paramsで投稿画像のみを生成し、保存ができた時と出来なかった時のフィードバックを表示します。

「topics/new.html.erb」でHTMLを書いていきます。

 

投稿一覧表示

コントローラーの「topics_controller.rb」ファイルに、indexアクションを作ります。

後は、View(index.html.erb)を作成すれば、投稿一覧を表示できます。

 

投稿写真の制限

今のままでは、投稿できる写真のファイル形式やデータサイズがバラバラです。

そこで、「uploaders/image_uploader.rb」にバリデーションを設定します。

例)

投稿できるファイル形式がjpg、jpeg、pngのみに制限する

def extension_white_list

%w(jpg jpeg png)

end

投稿できるサイズを10M以下に制限する

def size_range

1..10.megabytes

end

 

投稿ページへのアクセス

今の設定では、直接「topic/new」とURLを打つと、ログインしていない状態でも移動出来てしまいます。

そこで、「topics_controller.rb」で、ログイン状態でのみnewアクションにアクセス出来るように条件分岐するひち用があります。

def new
if logged_in?
@topic = Topic.new
else
redirect_to login_path, info: 'ログインして下さい'
end
end

 

最後に

備忘録がわりに作ったので、間違っている所とかあったら、コメントくれると嬉しいです。

-Ruby / Rails
-

© 2024 Nanayaku blog Powered by AFFINGER5