LoginSignup
0
0

More than 1 year has passed since last update.

rails5 progate 整理メモ テーブルの紐付け

Last updated at Posted at 2022-05-16

各投稿者が「誰がその投稿をしたか」という情報を持っている必要
postテーブルにuser_idカラムを追加する

rails g migrationを用いる。
add_user_id_to_postsというファイル名のマイグレーションファイルを作成します。

rails g migration add_user_id_to_posts

マイグレーションファイルを作成する。

class AddUserIdToPosts < ActiveRecord::Migration[5.0]
  def change
    add_column :posts, :user_id, :integer
  end
end

マイグレーションファイルの中身を編集する
postsテーブルにuser_idカラム(整数型)を追加する

rails db:migrate

マイグレーションファイルを編集した後はこれをやる。

バリデーションを行う。

class Post < ApplicationRecord
  validates :content, {presence: true, length: {maximum: 140}}
  validates :user_id, {presence: true}
  
end

新規投稿をログインユーザーに紐付けよう

誰が投稿したのかがわかるようになった。

ログインしているユーザーが投稿する

posts_controller.rb
 def create
    @post = Post.new(
      content: params[:content],
      # user_idの値をログインしているユーザーのidにしてください
      user_id: @current_user.id
    )

これで作成されるときにログイン中のユーザーのidが入るのかな。

成功。

投稿にユーザー情報を表示しよう

投稿の詳細ページにユーザー画像と名前を表示させる。

user_idカラムから情報を取ってくる。

user_idカラムの値から、そのユーザーの情報を取得する必要があります。
showコントローラでインスタンス変数に代入させる。

posts_controller.rb
  def show
    @post = Post.find_by(id: params[:id])
    # 変数@userを定義してください
    @user = User.find_by(id: @post.user_id)
    
  end

これでuser_idを基にUserのデータを引っ張ってくる。

SyntaxError in PostsController#show

app/views/posts/show.html.erb:11: syntax error

解決

<% link_to("#{@user.name}", "/users/#{@user.id}") 
<% link_to("#{@user.name}", "/users/#{@user.id}") %>

%>で閉じていなかったためだ。

imgタグのsrcの値は、「<%= "/user_images/#{@user.image_name}" %>」としてください

publicファイルから画像のデータを取り出さなくてはいかないから/user_images/から書かなくてはならない。

 <img src="<%= "/user_images/@user.image_name" %>">

あとブラウザに表示させるために<%= %>をつけなくてはならない。

<img src="<%= "/user_images/#{@user.image_name}" %>">

埋め込みrubyを使うため#{}で囲まなければ値が表示されない。

インスタンス変数を使ったリンクの書き方

<%= link_to( @user.name, "/users/#{@user.id}") %>

リンクに表示させる文字列にインスタンス変数を使う場合は埋め込みrubyは使わない。
ブラウザに表示させるときは<%= %>を使う。

インスタンスメソッドを定義しよう

Postモデル内で定義したインスタンスメソッドは、右の図のようにpostインスタンスに対して用いることができます。
モデル内でメソッドを作成することができる。そのモデルのインスタンスに用いることができる。

Postモデル内にその投稿に紐付いたuserインスタンスを戻り値として返すuserメソッドを定義しましょう。

post.rb
class Post < ApplicationRecord
.
.
.
  # インスタンスメソッドuserを定義してください
  def user
    return User.find_by(id: self.user_id)
  end 
end

selfはインスタンスメソッド内でそのインスタンス自信を表す。
この場合はpostモデルを表す。

[1] pry(main)> post = Post.find_by(id: 1)
  Post Load (0.1ms)  SELECT  "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
=> #<Post:0x000056459798d6f8
 id: 1,
 content: "hogehoge\r\n",
 created_at: Mon, 16 May 2022 14:25:03 JST +09:00,
 updated_at: Mon, 16 May 2022 14:25:03 JST +09:00,
 user_id: 1>

[2] pry(main)> post.user
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
=> #<User:0x00005645978be808
 id: 1,
 name: "にんじゃわんこ",
 email: "wanko@prog-8.com",
 created_at: Tue, 18 Apr 2017 17:06:52 JST +09:00,
 updated_at: Tue, 18 Apr 2017 17:06:52 JST +09:00,
 image_name: "default_user.jpg",
 password: "ninjawanko">

変数post(Postモデル)がインスタンスメソッドuserを使うことによってUserモデルの情報を取り出すことができるのか。

思ったこと

紐付けをしてあるとモデル同士を跨ぐことができるのか。

インスタンスメソッドを用いる

@user@postを用いてUserインスタンスを取り出す

@user = User.find_by(id: @post.user_id)

インスタンス変数を用いる

@user = @post.user

思ったこと

インスタンスメソッドを使うことによって見た目が簡単になった。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0