ここでは画像投稿機能を追加する方法について書いています。
Twitter風やInstagram風など、テキストだけではなく画像なども投稿する機能が欲しい場合は「CarrierWave」というgemを追加します。
環境
Windows10
VS code
ruby 2.7
Rails 6.1.4
二つのgemを導入する
ひな形の準備:scaffold
画像投稿機能:CarrierWave
#まずはscaffoldというgemでモデルやコントローラー、ビューを一括で作成
railsではモデルやビューやコントローラなどを作る必要があります。
いちから作っていると面倒なので「scaffold」というgemを使います。
railsアプリケーションの開発をする際には、モデルやコントローラー、ビュー、ルーティングを作成していく必要があります。
##modelsやviews、controllersの確認
通常、rails newでフォルダを作ると、app直下にmodels、views、controllersなどのファイルが格納されるフォルダが出来上がります。
app
にあるcontrollers
の中を見ると、concerns
というフォルダとapplication_controller.rb
というファイルがあるだけです。
ここへ新たにコントローラーファイルを作るというわけです。
###モデルやviewも確認
modelフォルダにはapplication_record.rbなどがあり、
viewフォルダにはapplication.html.erbやmailer.html.erbなどがあります。
このようにファイルがありますが、ここへも新しくヴューやモデルファイルも追加します。
railsにはscaffoldというgemを使うことでひな形を一気に作成し、ここでの作業をまとめて行ってくれます。それがscaffoldです。
##scaffoldのインストール
###ターミナルでコマンド入力
rails generate scaffold user name:string age:integer
意味
rails generate scaffold user name:string age:integer
rails generate scaffold モデル名 カラム名:データ型 カラム名:データ型
実行すると以下のような感じでできると思います。
PS C:\aaac> rails generate scaffold user name:string age:integer
invoke active_record
create db/migrate/20210817130706_create_users.rb
create app/models/user.rb
invoke test_unit
create test/models/user_test.rb
create test/fixtures/users.yml
invoke resource_route
route resources :users
invoke scaffold_controller
create app/controllers/users_controller.rb
invoke erb
create app/views/users
create app/views/users/index.html.erb
create app/views/users/edit.html.erb
create app/views/users/show.html.erb
create app/views/users/new.html.erb
create app/views/users/_form.html.erb
invoke resource_route
invoke test_unit
create test/controllers/users_controller_test.rb
create test/system/users_test.rb
invoke helper
create app/helpers/users_helper.rb
invoke test_unit
invoke jbuilder
create app/views/users/index.json.jbuilder
create app/views/users/show.json.jbuilder
create app/views/users/_user.json.jbuilder
invoke assets
invoke scss
create app/assets/stylesheets/users.scss
create app/views/users/edit.html.erb
create app/views/users/show.html.erb
create app/views/users/new.html.erb
create app/views/users/_form.html.erb
invoke resource_route
invoke test_unit
create test/controllers/users_controller_test.rb
create test/system/users_test.rb
invoke helper
create app/helpers/users_helper.rb
invoke test_unit
invoke jbuilder
create app/views/users/index.json.jbuilder
create app/views/users/show.json.jbuilder
create app/views/users/_user.json.jbuilder
invoke assets
invoke scss
create app/assets/stylesheets/users.scss
invoke scss
create app/assets/stylesheets/scaffolds.scss
##マイグレーションファイルなどが生成
db
フォルダの中にmigrate
というフォルダがあります。
この中に、作成した日付がかかれたファイルがあります。
これが先ほど、rails generate scaffold user name:string age:integer
とコマンド入力したときに作られたデータベースのカラム
となるファイルです。
###生成されたマイグレーションファイルの内容
create_table :users do |t|
t.string :name
t.integer :age
これでマイグレーションファイルは出来上がりました。
けれどこれだけではデータベースが完成していません。
このあと、rails db:migrateもしくはrake db:migrate
というコマンド入力をしてデータベースのテーブルを作成します。
※ railsとrakeの違い、rails5以降はrailsに統一されたのでどっちを使ってもよいと思います。
###rails db:migrateを実行
rails db:migrate
###「schema.rb」「development.sqlite3」ファイルの確認
「schema.rb」「development.sqlite3」というファイルが作成されておりますのでこちらも確認します。
####「schema.rb」ファイルを確認
ActiveRecord::Schema.define(version: 2021_08_17_130706) do
create_table "users", force: :cascade do |t|
t.string "name"
t.integer "age"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
end
###users_controller.rb
ディレクトリを確認すると下記のようにusers_controller.rbというファイルができています。
####view>usersにもそれぞれのファイルが作られています。
##サーバーを起動させviewから確認
できあがったのでサーバーを立てるため下記コマンド入力
rails s
立ち上がったら下記URLへ
http://localhost:3000/users
###ページが表示されない場合
http://localhost:3000/users
が表示されない場合は、
下記URLにてTOPページを確認してください。
http://localhost:3000/
TOPページが表示されていればサーバー自体は起動して表示することに関しては問題ありません。
##scaffoldインストール後の使い方
まず、下記のページが表示されています。
###scaffoldでフロントエンドからユーザのデータを作成
New User
をクリックしてユーザーのデータを作ります。
下記ページが表示されます。
NameとAgeにそれぞれ名前と年齢を入れます。
あとはCreate User
をクリックします。
すると以下のように表示されます。
なおページURLは/user/1となっています。
Edit | Back
とありますが、Edit は編集ページに移動します。Backを押すとユーザー一覧ページへ移動します。
同じようにユーザーを登録してみると出来上がりをイメージしやすいかもしれません。
以上になります。
#【本題】CarrierWaveを導入する(scaffoldに画像投稿機能を追加する)
##gemfileに記述
CarrierWaveを導入するために、gemfile
というファイルに下記コマンドを記述する。
gem 'carrierwave'
###gemfile
を開き、一番下に上記のコードを追加します。
###CarrierWaveをインストールするためにbundle install
を実行
あとはCarrierWaveをインストールするためにbundle install
を実行します。
bundle install
インストールされているリストの中で、using CarrierWave
があれば無事に完了しています。
#CarrierWaveを有効にするために再起動をします
再起動はCtrl+C
で停止にして、rails s
で起動させます。
##アップローダークラスの作成
アップローダークラスのファイルを作成すると、アップロードするときの設定をつくれます。
ファイルのサイズ、拡張子、保存先などを指定する事が出来ます。
画像投稿用としてimgでコマンドを実行します。
img
以外の文字でも大丈夫です。
入力コード例
bundle rails g uploader img
ファイルはapp>uploader>img_uploader
にあります。
ひとまずアップロードができればよいので、ここで細かい設定などの説明は割愛します。
##投稿画像が保存される場所 画像のアップロード先
img_uploaderには下記のように書かれています。
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
したがって、uploadsのフォルダ内となります。
##投稿する画像の情報をカラムを追加
さきほど、scaffold
でカラムを作りました。
カラムの確認方法は、dbフォルダ内のschema.rb
です。
現在は下記のようになっています。※SQLITEの場合
ActiveRecord::Schema.define(version: 2021_08_17_130706) do
create_table "users", force: :cascade do |t|
t.string "name"
t.integer "age"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
end
end
###ここへ画像を保存するカラムを追加します。
rails g migration add_img_to_users img:string
※rails g migration Addカラム名Toテーブル名 カラム名:データ型
カラム名になる部分は任意。
###マイグレーションを実行してデータベースのテーブルへ追加
rails db:migrate
追加後、dbフォルダにあるschema
ファイルを確認します。
t.string "img"
が追加されています。
##controllerにimgカラムを追加
データベースに保存するためにcontroller
フォルダにあるusers_controller
ファイルにカラムを追加します。
ageのあとに, :img
を追加します。
def user_params
params.require(:user).permit(:name, :age, :img)
end
##投稿画像の設定をするアップローダークラスとカラム名imgを紐付ける
models
フォルダにuser.rb
というファイルがあるのでそこを開きます。
ここへ下記コードを書き込みます。
class User < ActiveRecord
mount_uploader :img, ImgUploader
end
画像投稿時に、アップローダークラスに書かれている設定が反映されます。つまり画像のサイズや画像の投稿フォルダや拡張子などです。
##注意 user.rbファイル class User < ActiveRecord
class User < ActiveRecord
の部分で下記のようにするとエラーになります。
class User < ActiveRecord::Base
#viewsの設定 投稿フォームに画像が投稿できるようにする
次はフロントエンド側の設定です。
下記のように、まだ画像を投稿するフォームがありません。
画像を投稿するようにします。
まずusers
フォルダへ移動して_form.html.erb
を開きます。
名前や年齢の下に入れたいので下記コードを貼ります。
<div class="field">
<%= form.label :img %>
<%= form.file_field :img %>
</div>
localhost:3000/users/newを表示
ファイルが投稿できるようになっています
###表示させる部分show.html.erbにコード追記
下記のコードをusers>show.html.erbのファイルのageの下に貼り付けます。
<% if @user.img? %>
<p>
<strong>post img:</strong>
<%= image_tag @user.img.url %>
</p>
<% end %>
##動作確認のためユーザ登録を表示させる
適当に名前や年齢をいれ、画像も入れます
以上になります。