【Railsチュートリアル】「2.3.3 ユーザーはたくさんマイクロポストを持っている」の演習へのアプローチ記録
目的
ユーザーのshowページを編集し、ユーザーの最初のマイクロポストを表示する。
views/users/show.html.erb
を編集
まず、views/microposts/show.html.erb
の内容を確認すると、下記コードでポスト内容を表示している。
<p>
<strong>Content:</strong>
<%= @micropost.content %>
</p>
なので、views/users/show.html.erb
にそれを追記する。
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= @user.name %>
</p>
<p>
<strong>Email:</strong>
<%= @user.email %>
</p>
<p>
<strong>First_Content:</strong>
<%= @micropost.content %>
</p>
<%= link_to 'Edit', edit_user_path(@user) %> |
<%= link_to 'Back', users_path %>
そして、ブラウザ更新。
「undefined method
content' for nil:NilClass」というエラーメッセージが表示される。 ビュー
app/views/users/show.html.erbはコントローラ
app/controllers/users_controller.rbから呼ばれている。 usersコントローラにはインスタンス変数
@contentは定義されていないので、先ほどのエラーになったのかと納得。 では、どうすればいいのか。インスタンス変数
@userを利用して、
@user.content`のようにデータ指定すればよいのではないかと考えられるので、それをどうすれば実現できるかを考える。
@user.content
でデータ表示できないかを考える。
@user.content
を使えるようにするには、まず、@user
に登録されているデータを調べることから始める。
データベースとのやりとりは、モデルapp/models/user.rb
が行っているので、それを確認。
class User < ApplicationRecord
has_many :microposts
end
と、このファイルを確認したことで、この演習の前のステップで、has_many :microposts
を記述し、異なるデータモデル同士の関連付けを行っていたことを思い出した。
これを利用してこの演習をするのだなと思い、再び、チュートリアルの記述を確認。
すると、micropost = first_user.microposts.first
で最初のユーザーの最初のポスト内容をもってくるとあるので、これを使えないか考える。
app/controllers/users_controller.rb
を確認すると、
private
# Use callbacks to share common setup or constraints between actions.
def set_user
@user = User.find(params[:id])
end
という処理があり、インスタンス変数の@user
にはユーザーIDが入っているとわかる。
ということは、micropost = first_user.microposts.first
を@user.micropost.first
とすることで、該当ユーザーの最初のポスト内容が取得できるはずなので、app/views/microposts/show.html.erb
をそのように編集する。
app/views/microposts/show.html.erb
の編集
app/views/users/show.html.erb
に@user.micropost.first
を記載。
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= @user.name %>
</p>
<p>
<strong>Email:</strong>
<%= @user.email %>
</p>
<p>
<strong>First_Content:</strong>
<%= @user.microposts.first %>
</p>
<%= link_to 'Edit', edit_user_path(@user) %> |
<%= link_to 'Back', users_path %>
そして、ブラウザを更新。
うまくデータを取得できていないようだ。。
一旦。コマンド"docker-compose run --rm web exec rais c
"でコンソールを開き、テーブルの中身を確認する。
masa@DESKTOP-0CNPS43:~/RailsTutorial$ docker-compose run --rm web bundle exec rails c
Creating railstutorial_web_run ... done
Loading development environment (Rails 6.1.0)
irb(main):001:0> User.all
User Load (0.2ms) SELECT "users".* FROM "users" /* loading for inspect */ LIMIT $1 [["LIMIT", 11]]
=> #<ActiveRecord::Relation [
#<User id: 1, name: "masa", email: "masaa@gmail.com", created_at: "2021-01-04 22:16:17.756753000 +0000", updated_at: "2021-01-04 22:18:08.383711000 +0000">,
#<User id: 5, name: "aiku", email: "aiku@gmail.com", created_at: "2021-01-05 04:46:12.228101000 +0000", updated_at: "2021-01-05 04:46:12.228101000 +0000">,
#<User id: 6, name: "syanon", email: "syanon@nikoniko.com", created_at: "2021-01-05 04:49:40.646040000 +0000", updated_at: "2021-01-05 04:49:40.646040000 +0000">]>
irb(main):002:0>
irb(main):003:0> Micropost.all
Micropost Load (0.4ms) SELECT "microposts".* FROM "microposts" /* loading for inspect */ LIMIT $1 [["LIMIT", 11]]
=> #<ActiveRecord::Relation [
#<Micropost id: 1, content: "goodmornig", user_id: 1, created_at: "2021-01-05 00:43:15.463431000 +0000", updated_at: "2021-01-05 00:43:15.463431000 +0000">,
#<Micropost id: 3, content: "a", user_id: 1, created_at: "2021-01-05 00:44:37.269892000 +0000", updated_at: "2021-01-05 00:44:37.269892000 +0000">,
#<Micropost id: 8, content: "aiku", user_id: 5, created_at: "2021-01-05 04:52:41.125643000 +0000", updated_at: "2021-01-05 04:52:41.125643000 +0000">,
#<Micropost id: 9, content: "syanon", user_id: 6, created_at: "2021-01-05 04:52:53.550736000 +0000", updated_at: "2021-01-05 04:52:53.550736000 +0000">]>
データをみると、登録データは問題なさそう。
コンソール上で@user.microposts.first
を確認する。
@user.microposts.first
"を確認する。
コンソール上で"@userをコンソールでつかえるように翻訳しないといけないが、一旦"Micropost.first
"を確認。
irb(main):010:0> Micropost.first
Micropost Load (0.3ms) SELECT "microposts".* FROM "microposts" ORDER BY "microposts"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> #<Micropost id: 1, content: "goodmornig", user_id: 1, created_at: "2021-01-05 00:43:15.463431000 +0000", updated_at: "2021-01-05 00:43:15.463431000 +0000">
これだと、user_id = 1
のカラムが抜き出されている。
ということは、さらに、content
の中身が取得できるようにするには、Micropost.first.content
とすればよいのではないか。
irb(main):011:0> Micropost.first.content
Micropost Load (0.4ms) SELECT "microposts".* FROM "microposts" ORDER BY "microposts"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> "goodmornig"
goodmoning
キタ━━━━(゚∀゚)━━━━!!
これをapp/views/users/show.html.erb
に反映させる。
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= @user.name %>
</p>
<p>
<strong>Email:</strong>
<%= @user.email %>
</p>
<p>
<strong>First_Content:</strong>
<%= @user.microposts.first.content %>
</p>
<%= link_to 'Edit', edit_user_path(@user) %> |
<%= link_to 'Back', users_path %>
ブラウザを更新した結果、、、
goodmoning
キタ━━━━(゚∀゚)━━━━!!
~fin~