kota-6211
@kota-6211

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

ruby on railsでrender を使ったリロードエラーについて

ruby one rails についての質問です。
新規投稿をしたとき、空欄のままクリックするとエラーメッセージがでてくるようにしました。
しかしエラーメッセージが出てからリロードをすると url  が変わってエラーになってしいます。
自分で調べてみたところ、 render ではなく  redirect_to を使うと解消できるという記述が多かったので試してみたところエラーにならなくなりました。
しかしエラーメッセージが消えてしまうので、エラーメッセージはそのままリロードできるようにしたいです。
ルートを無理やり変えてエラーにならなくしても、同じくエラーメッセージは消えてしまいます。
どなたかご教授ください。よろしくお願いします。

以下 コードになります。

##routes

Rails.application.routes.draw do
get 'books/new' => 'books#new'
get 'books/index' => 'books#index',as: 'index_book'
post 'books' => 'books#create'
delete 'books/:id' => 'books#destroy',as: 'destroy_book'
get 'books/:id/show' => 'books#show',as: 'book'
get 'books/:id' => 'books#edit',as: 'edit_book'
patch 'books/:id' => 'books#update' ,as: 'update_book'
get '/' => 'homes#top'
end

##controller

class BooksController < ApplicationController

def index
@books = Book.all.order(created_at: :desc)
@book = Book.new
end
def create
@book = Book.new(book_params)
if @book.save
flash[:notice] = "Book was successfully created."
redirect_to book_path(@book)
else
@books = Book.all.order(created_at: :desc)
render 'index'
end
end
def destroy
@book = Book.find(params[:id])
@book.destroy
redirect_to '/books'
end

def show
@book = Book.find_by(id: params[:id])
end

def edit
@book = Book.find(params[:id])
end
def update
@book = Book.find(params[:id])
if @book.update(book_params)
flash[:notice] = "Book was successfully updated."
redirect_to book_path
else
render 'edit'
end
end

private
def book_params
params.require(:book).permit(:title ,:body)
end
end

##html

<% if @book.errors.any? %>
<%= @book.errors.count %>errors prohibited this book from being saved:
<% @book.errors.full_messages.each do |message| %>
<%= message %>
<% end %>
<% end %>

<%= form_with model: @book, url: books_path , local: true do |f| %>
 <p class="new-books-text">Title</p>
  <%= f.text_field :title ,class:"text-field"%>
  
  <div class="new-body">
    <p class="new-books-text">Body</p>
    <%= f.text_area :body ,class:"text-area"%>
  </div>
 
 <%= f.submit 'Create Books', class: "buttom"%>
 <% end %>
0

3Answer

参考になりそうな記事があったので提示します。

flashに[インスタンス変数].errors.full_messagesを入れておき、view側でflashから取り出します。


上記とは別に、質問する際に留意するべき2点を補足させてもらいます。
①Ruby、Railsのバージョン(+必要であれば実行環境など)を明記してください
 ・特にRailsはメジャーバージョン(7.x.xか6.x.xか5.x.x)の
  違いによって仕様が大きく異なるため重要です。

②コードはMarkdownの「コードブロック」を使用して記述した方が良いです
 ・可読性も格段に上昇しますし、
  回答者側も提示されたコードをすぐコピーして
  解読に利用することができるため回答率の上昇を期待できます。

上記②の「コードブロック」について不明な場合は
以下を参照してみてください。


例:この質問のコードを「コードブロック」を
利用して記載すると以下のように表示されます。
(こうなる、という例を提示するために長くなってしまうことをご了承ください)

※可読性向上の為、一部コード内容、インデント、ファイル名
など微調整を加えていますが、基本敵にコード内容は質問そのままです。
(問題解決していない状態のままです)

routes.rb
Rails.application.routes.draw do
  root to: 'home#top'

  get 'books/new' => 'books#new'
  get 'books/index' => 'books#index',as: 'index_book'
  post 'books' => 'books#create'
  delete 'books/:id' => 'books#destroy',as: 'destroy_book'
  get 'books/:id/show' => 'books#show',as: 'book'
  get 'books/:id' => 'books#edit',as: 'edit_book'
  patch 'books/:id' => 'books#update' ,as: 'update_book'
end
books_controller.rb
class BooksController < ApplicationController

  def index
    @books = Book.all.order(created_at: :desc)
    @book = Book.new
  end

  def create
    @book = Book.new(book_params)

    if @book.save
      flash[:notice] = "Book was successfully created."
      redirect_to book_path(@book)
    else
      @books = Book.all.order(created_at: :desc)
      render 'index'
    end
  end

  def destroy
    @book = Book.find(params[:id])
    @book.destroy
    redirect_to '/books'
  end

  def show
    @book = Book.find_by(id: params[:id])
  end

  def edit
    @book = Book.find(params[:id])
  end

  def update
    @book = Book.find(params[:id])

    if @book.update(book_params)
      flash[:notice] = "Book was successfully updated."
      redirect_to book_path
    else
      render 'edit'
    end
  end

  private

  def book_params
    params.require(:book).permit(:title ,:body)
  end
end

##html

「HTML」と「erb(ビューテンプレート)」は別モノなのでご注意ください

index.html.erb
<% if @book.errors.any? %>
  <%= @book.errors.count %>errors prohibited this book from being saved:
  <% @book.errors.full_messages.each do |message| %>
    <%= message %>
  <% end %>
<% end %>

<%= form_with model: @book, url: books_path , local: true do |f| %>
  <p class="new-books-text">Title</p>
  <%= f.text_field :title ,class:"text-field"%>
  
  <div class="new-body">
    <p class="new-books-text">Body</p>
    <%= f.text_area :body ,class:"text-area"%>
  </div>
 
   <%= f.submit 'Create Books', class: "buttom"%>
 <% end %>

「コードブロック」はマウスカーソルを乗せるとアイコン
(以下画像の赤枠参照)が表示され、
クリックすることで1ブロック全てをコピーすることができます。

copy.jpg

補足がだいぶ長くなってしまいましたが、提示した内容に
少しでも役に立つような情報があれば幸いです。

1Like

Comments

  1. @kota-6211

    Questioner

    ありがとうございます!!
    参考にさせていただきます!

答えになってなかったら申し訳ございませんですが、
jsで空白とかのバリデーションの処理をしてたら上記なことは起きないと思います。

0Like

その問題のページを

「GET でも POST でもアクセスできるよう routes 設定を行う」を試してみてくださいませ。

0Like

Your answer might help someone💌