2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Railsでモデルに書いたメソッドをrails consoleで検証してみた

Last updated at Posted at 2024-04-03

この記事を書いた目的

Railsでコードを書く際にモデルにインタンスメソッドを定義をして、コントローラで呼び出すことがよく行われるということを学びました。少し調べてみると、このことは主にファットコントローラを避けることを目的として行われているようです。
ただ、初心者の私からすると「コントローラの流れすら追うのに苦労しているというのに、別の場所に定義したメソッドを呼び出すなんて、わけわかめ!」ということで、実際にコンソールを動かしてどういった動きをしているのか確かめてみました。

今回検証したコード

掲示板作成アプリ内のお気に入り登録ができる機能に関わる箇所です。該当のコントローラとモデル内のインスタンスメソッドは下記の通りです。

bookmarks_controller.rb
 def create
    board = Board.find(params[:board_id])
    current_user.bookmark(board)
    #...
 end
user.rb
def bookmark(board)
    bookmark_boards << board
end
  • Userモデル内に作成したbookmarkの登録用メソッドを、bookmarksコンローラで呼び出すという流れです

Bookmarkテーブル作成時のマイグレーションファイル

XXXXXXX_create_bookmarks.rb
class CreateBookmarks < ActiveRecord::Migration[7.0]
  def change
    create_table :bookmarks do |t|
      t.references :user, null: false, foreign_key: true
      t.references :board, null: false, foreign_key: true

      t.timestamps
      t.index [:user_id, :board_id], unique: true
    end
  end
end

UserテーブルとBoardテーブルの中間テーブルです。また、同じユーザーが同じ投稿に対して2度ブックマーク登録を行うことのないよう、user_idboard_idにユニーク制約をかけることで、データベースレベルで一意性を保つようにしてあります。

rails consoleの起動(Docker使用時)

$ docker compose run web bin/rails console

RailsConsoleで流れを確認する

今回コンソールで検証するuser_id=1とboard_id=1の組み合わせでは、ブックマークが作成されていません。では、先ほどのコントローラー流れを1行ずつコンソールで確かめていきましょう。

board = Board.find(params[:board_id])

irb(main):002:0> sample_board = Board.find_by(id: 1)
  Board Load (1.1ms)  SELECT `boards`.* FROM `boards` WHERE `boards`.`id` = 1 LIMIT 1
  • Boardモデルからid=1のデータを取得し、sample_boardという変数に代入します

current_user.bookmark(board)

irb(main):003:0> User.find_by(id: 1).bookmark(sample_board)

こちらで実行した内容としては下記の通りです。

  • Userモデルからid=1のデータを取得します(コントローラではsorceryのメソッドcurrent_userで呼び出しています)
  • 上のuserのデータに対して、引数sample_boardとってbookmarkメソッドを呼び出します

ではコンソールの実行結果を見ていきます。

  User Load (1.2ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
  TRANSACTION (0.4ms)  BEGIN
  • Userモデルからid=1のデータを取得します
  Bookmark Exists? (0.4ms)  SELECT 1 AS one FROM `bookmarks` WHERE `bookmarks`.`user_id` = 1 AND `bookmarks`.`board_id` = 1 LIMIT 1
  • 同じuser_idboard_idの組み合わせが既にBookmarkテーブルにないかを確認しています
  Bookmark Create (1.0ms)  INSERT INTO `bookmarks` (`user_id`, `board_id`, `created_at`, `updated_at`) VALUES (1, 1, '2024-03-31 11:40:52.618794', '2024-03-31 11:40:52.618794')
  TRANSACTION (1.2ms)  COMMIT  
  • ここでbookmarkメソッドが呼び出されています
  • <<演算子はhas_many関連付けで使用可能になるメソッドです
    4.3.1.2 collection<<(object, ...)
    Array#<< (Ruby 3.3 リファレンスマニュアル)
  • bookmark_boards << boardは、bookmarks.create!(board_id: board.id)と同様の処理が行われるため、SQLでCREATE文が発行されます
  • コミットすることでBookmarkテーブルにデータが保存されました

まとめ

rails consoleで実際の流れを把握することで、コードに対する理解が深まったように感じました。まだまだ理解のできてない箇所があるので、誤っている点などあれば教えていただけると嬉しいです!

参考

2
1
1

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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?