ここでは画像投稿機能を追加する方法について書いています。
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 %>
##動作確認のためユーザ登録を表示させる
適当に名前や年齢をいれ、画像も入れます
以上になります。
















