rails turtorial 第2章
scaffold で簡単なデモアプリを作る
※gemファイルの更新,クラウドIDEの設定,gitレポジトリの設定は終了している前提で進めます
また、実際にコードを書く部分だけさくっと記述しています。詳しい仕組みや説明はRails Tutorialを参照してください
1、scafffoldでUserリソースを作成
$ rails generate scaffold User name:string email:string
実行すると以下のデータベースが作成される
2、データベースをマイグレート
$ rails db:migrate
== CreateUsers: migrating ======================================
-- create_table(:users)
-> 0.0027s
== CreateUsers: migrated (0.0036s) =============================
users_controllerファイル内に以下のアクションが追加されます。
class MicropostsController < ApplicationController
before_action :set_micropost, only: %i[ show edit update destroy ]
# GET /microposts or /microposts.json
def index
@microposts = Micropost.all
end
# GET /microposts/1 or /microposts/1.json
def show
end
# GET /microposts/new
def new
@micropost = Micropost.new
end
# GET /microposts/1/edit
def edit
end
# POST /microposts or /microposts.json
def create
@micropost = Micropost.new(micropost_params)
respond_to do |format|
if @micropost.save
format.html { redirect_to micropost_url(@micropost), notice: "Micropost was successfully created." }
format.json { render :show, status: :created, location: @micropost }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @micropost.errors, status: :unprocessable_entity }
end
end
end
これで末尾にUsersページやeditページ(userの編集ページ)などのページが作成されました。
一度ルートURLに/usersを入力し、Usersページが開くのを確認しましょう。
その後下記画像のように何でも良いのでnameとemailに名前とemailを適当に入力して「create user」をクリックしましょう。
これで新しいユーザーが作成されました。
ご覧のように、各種ボタンも追加されています
- 「Edit this user」 ユーザー情報を編集
- 「Back to users」 ユーザー一覧ページに戻る
- 「destroy this user」 現在選択しているユーザーを削除する
これで新しいユーザーの編集や追加、削除などが出来るので、一通り試してみましょう。
MVCの挙動
MVCの挙動を一通り理解したところで、config/routes.rbに以下のコードを加えます
Rails.application.routes.draw do
resources :users
root 'users#index'
end
これにより最初のアクセスページが/usersのページにアクセスされるようになります。
第2章で進めて行く上で必要な記述すべきコードのみを載せていますが、MVCの挙動、Railsがどんな動きをしているかは、直接Rails Tutorialを参照してください
Micropostsリソース
Usersリソースを作ったのと同様に、Microposts(投稿)のページとアクション等を生成します
rails generate scaffold Micropost content:text user_id:integer
$ rails db:migrate
== CreateMicroposts: migrating ===============================================
-- create_table(:microposts)
-> 0.0023s
== CreateMicroposts: migrated (0.0026s) ======================================
config/routesにマイクロポスト用のURIを割り当てる
Rails.application.routes.draw do
resources :microposts
resources :users
root 'users#index'
end
/usersの時と同じように、/micropostsを末尾に入力することでmicropostを投稿することが出来るので、/usersの時と同じ要領でmicropostを投稿したり、編集したりしてみましょう。
マイクロポストをマイクロにする
マイクロポストに140文字の制限を加える
「app/models/micropost.rb」に以下の文言を加える
class Micropost < ApplicationRecord
validates :content, length: { maximum: 140 }
end
これで140字を超えるとエラーが出るか確認してみましょう。
Content is too longという記述があれば成功です。
ユーザーはたくさんマイクロポストを持っている
先ほど作成したusersモデルとmicropostsを紐付けます
app/models/user.rb
class User < ApplicationRecord
has_many :microposts #1人のユーザーに複数のマイクロポストがある。
end
app/models/micropost.rb
class User < ApplicationRecord
class Micropost < ApplicationRecord
belongs_to :user #1つのマイクロポストは1人のユーザーにのみ属する。
validates :content, length: { maximum: 140 }
end
rails consoleにて以下の作業を順に行ってみてください
$ rails console
>> first_user = User.first
>> first_user
>> first_user.microposts
>> micropost = first_user.microposts.first
>> micropost
>> micropost.user
>> exit
最初のユーザーの情報や、投稿の情報などが表示されていることを確認してみましょう。
※ここでの演習について
ユーザーのshowページを編集し、ユーザーの最初のマイクロポストを表示してみましょう。同ファイル内の他のコードから文法を推測してみてください(コラム 1.2で紹介した技術の出番です)。うまく表示できたかどうか、/users/1にアクセスして確認してみましょう。
これに関して私は躓いたのですが、いろいろ調べたりした結果、以下のようなコードを書くのが答えのようです。
app/views/users/show.html.erb
<p style="color: green"><%= notice %></p>
<%= render @user %>
#ここから追加
<strong>Microposts</strong>
<%= @user.microposts.first.content %>
#ここまで
<div>
<%= link_to "Edit this user", edit_user_path(@user) %> |
<%= link_to "Back to users", users_path %>
<%= button_to "Destroy this user", @user, method: :delete %>
</div>
これによって登録されたユーザーの最初の投稿が反映されます
ただし登録したユーザーが投稿していない場合や、2つのデータベースが上手く紐付いていない場合
以下のようなエラーが表示されます。
「undifined method content for NillClasds」
コンテントを表示したいけど、@user.micropoosts.firstがない場合、以下のエラーが出ます。
例えば2人のユーザーを登録したけれど、2人目のマイクロポストを作成していない場合など
以下のエラーが出てしまいます。私の場合はshowページのみならず編集ページなどをクリックした場合でもこのようなエラーが出てしまい、なんだか気持ち悪いです。
なので、このようなエラーが出た場合は、このコードを追加しましょう
<p style="color: green"><%= notice %></p>
<%= render @user %>
#下記1行を追加
<% if @user.microposts.present? %>
<p>
<strong>Microposts</strong>
<%= @user.microposts.first.content %>
</p>
#endを追加
<% end %>
<div>
<%= link_to "Edit this user", edit_user_path(@user) %> |
<%= link_to "Back to users", users_path %>
<%= button_to "Destroy this user", @user, method: :delete %>
</div>
<% if @user.microposts.present? %>
presentメソッドは、変数の値が存在するか、しないかによって後続の処理を変更したい場合に使用し、ここでは @user.microposts.first.contentが存在しない場合、falseを返します。つまり最初の投稿があれば表示し、なければ表示しないというメソッドを使用します。
<% end %>を忘れずに追加しましょう。
ターミナル上で現在のデータベースの情報を調べる方法
$ rails dbconsole
SQLite version 3.40.1 2022-12-28 14:03:47
Enter ".help" for usage hints.
sqlite> .table
ar_internal_metadata schema_migrations
microposts users
作成したマイクロポストとユーザーのモデルが表示されます。
sqlite> select * from users;
13|sample|sample@gmail.com|2023-08-30 07:37:03.090880|2023-08-30 07:37:03.090880
14|sample2|sample2@gmail.com|2023-08-30 07:47:31.315615|2023-08-30 07:47:31.315615
select * from モデル名;
で選んだモデルの全てのデータを表示することが出来ます。SQLで使用する記述方法ですね。
私の場合は2つのユーザーの情報のIDが13,14となっています。これはなぜかというと、1,2,3とユーザを作った場合は同じようにIDも1,2,3と振られる訳ですが、例えばIDが1のユーザーを削除した場合、次に作るユーザーのIDは4となり、2,3,4という順番になる訳です。私の場合削除を繰り返し新しくつくった2人のユーザーは13番目、14番目となってしまったわけです。
たまにマイクロポストでユーザを選ぶときに「user must exist」で選べないときは、そのIDのユーザを消してしまって、今いるユーザーのID何だっけ?となる時もあるので、この方法で確認してみましょう。
まあ、ルートURLを見ればIDは分かるのですが
あとは演習通り、マイクロポストのコンテンツが存在していない場合エラーが出るように以下のコードを追加して、検証してみましょう
app/models/micropost.rb
class Micropost < ApplicationRecord
belongs_to :user
validates :content, length: { maximum: 140 },
presence: true #空欄の時にエラーが出る
end
app/models/user.rb
class User < ApplicationRecord
has_many :microposts
validates :name, length: { maximum: 140 },presence: true
validates :email, length: { maximum: 140 },presence: true
end
後は演習に従ってgitにプッシュし、renderで表示できるか確認してみましょう。