掲示板実装③ 関連付けモデルのcreateアクション
実装時の最初のコード
def create @board = Board.new(board_params) @board.user_id = current_user.id debugger if @board.save flash[:success] = t('defaults.message.new_board_was_created') redirect_to boards_path . . . private def board_params params.require(:board).permit(:title, :body) end
これで実行したところエラーが発生
Started POST "/boards" for ::1 at 2020-10-22 11:58:26 +0900 Processing by BoardsController#create as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"i+2YvOizuA+ssszr3qeVbjJoR2GhLPRyiizTuclusxtL998Pvb5XoAlay4GxOL9QmSUIhqEZLZLUtcP2pwf0BQ==", "board"=>{"title"=>"いかが?", "body"=>"いい感じ"}, "commit"=>"登録する"} User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 21], ["LIMIT", 1]] ↳ vendor/bundle/ruby/2.6.0/gems/activerecord-5.2.3/lib/active_record/log_subscriber.rb:98 (0.1ms) begin transaction ↳ app/controllers/boards_controller.rb:12 (0.1ms) rollback transaction ↳ app/controllers/boards_controller.rb:12 Rendering boards/new.html.erb within layouts/application Rendered boards/new.html.erb within layouts/application (3.9ms) Rendered shared/_header.html.erb (7.1ms) Rendered shared/_flash_message.html.erb (0.5ms) Rendered shared/_footer.html.erb (0.6ms) Completed 200 OK in 186ms (Views: 177.9ms | ActiveRecord: 0.4ms)
サーバーログを見るとrollback transactionが発生していた。 バリデーションエラーが起こってる?
debuggerを挟んでparamsの中身をチェック
(byebug) params <ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"0JLIVzGzOZq3K68t7TXgguDQg3Kzs5bAK29rmjVbrhwQiI/kZL7WNRLDqEeCqsq8S53MlbOGTyB19nvVWzLpAg==", "board"=><ActionController::Parameters {"title"=>"いかが?", "body"=>"いい感じ"} permitted: false>, "commit"=>"登録する", "controller"=>"boards", "action"=>"create"} permitted: false> (byebug) @board #<Board id: nil, title: "いかが?", body: "いい感じ", user_id: nil, created_at: nil, updated_at: nil> (byebug) @board.user_id nil (byebug) @board.user nil (byebug)
やっぱりuser_idがnilになっていて弾かれていた。 つまりuser_idを渡してあげればしっかりと動作するはず!
次のコード
def create @board = Board.new(board_params) @board.user_id = current_user.id if @board.save flash[:success] = t('defaults.message.new_board_was_created') redirect_to boards_path
If @board.saveの前に、@boardのuser_idを渡す一文を追加。 すると、今度は成功した!
しかし、モデル同士を紐付けしたのに、上記のコードではそのメリットを活かせていない。 紐付けをしていることにより、下のコードを使って一文で表すことができる
@board = current_user.boards.build(board_params)
ここでbuildを使っているのは、「モデルが関連付いているときは、buildを使う」というrailsの暗黙の了解のためであり、 newを使用してもしっかり動作する。