Search code examples
ruby-on-railserror-handlinggoogle-chrome-devtools

Rails error messages not appearing on website but showing in Chrome DevTools Network Preview


I'm trying to show error messages when creating a new instance of a model in my Rails app when a field doesn't pass validation. For some reason, the errors never actually show up on the website next to the fields like they're supposed to. However, the errors appear in the 'Preview' section of the Network tab of Chrome DevTools. So the errors are generating properly. In the terminal it says that new.html.erb is rendered but I don't think it actually does? Any help would be greatly appreciated - I haven't found much about this online. I'm using Tailwind CSS for styling the front end if that's helpful.

Here's my code:

occasion.rb

class Occasion < ApplicationRecord
    belongs_to :user
    has_many :registries
    has_many :charities, :through => :registries
    
    validates :occasion_name, presence: true
    validates :occasion_date, presence: true
    validates :url, presence: true, format: { without: /\s/ }, uniqueness: true
    validates_uniqueness_of :user_id

end

occasions_controller.rb

class OccasionsController < ApplicationController
  load_and_authorize_resource only: [:new, :create, :edit, :update, :destroy]

  def index
    @occasions = Occasion.all
  end
  
  def show
    @occasion = Occasion.where(url: params[:url]).first
  end
  
  def new
    @occasion = Occasion.new
  end

  def create
    @occasion = Occasion.new(occasion_params)
    @occasion.user = current_user

    if @occasion.save
      respond_to do |format|
        format.html { redirect_to new_registry_path }
        format.js   { render :js => "window.location='#{ new_registry_path }'" }
      end
    else
      render :new
    end
  end

  def edit
    @occasion = Occasion.find(params[:id])
  end

  def update
    @occasion = Occasion.find(params[:id])

    if @occasion.update(occasion_params)
      redirect_to @occasion
      return
    else
      render :edit
    end
  end

  def destroy
    @occasion = Occasion.find(params[:id])
    @occasion.destroy

    redirect_to occasions_path
  end

  private
    def occasion_params
      params.require(:occasion).permit(:user_id, :occasion_name, :occasion_date, :url)
    end
    
  # user authentication is not required for show
  skip_before_action :authenticate_user!, :only => [:show]


end

new.html.erb

<%= form_with model: @occasion do |form| %>

    <div class="text-center">
        <%= form.label :occasion_name, "Occasion Name", class: "text-red-400 font-semibold px-8" %><br>
        <%= form.text_field :occasion_name, class: "rounded w-2/5" %>
        <% @occasion.errors.full_messages_for(:occasion_name).each do |message| %>
        <div><%= message %></div>
        <% end %>
    </div>

    <div class="text-center py-2">
        <%= form.label :occasion_date, "Occasion Date", class: "text-red-400 font-semibold px-8" %><br>
        <%= form.date_field :occasion_date, type: "date", class: "rounded" %>
        <% @occasion.errors.full_messages_for(:occasion_date).each do |message| %>
        <div><%= message %></div>
        <% end %>
    </div>

    <div class="text-center py-2">
        <%= form.label :url, 'URL', class: "text-red-400 font-semibold px-8" %><br>
        <%= form.text_field :url, class: "rounded" %>
        <% @occasion.errors.full_messages_for(:url).each do |message| %>
        <div><%= message %></div>
        <% end %>
        <em><div class="text-sm">domainname.com/yourURLhere</div></em>
    </div>

    <div class="text-center py-2">
        <%= form.submit occasion.persisted? ? 'Update' : 'Save', class: "rounded-full bg-red-400 text-white px-3" %>
    </div>

<% end %>

Solution

  • From the provided information, it looks like the form gets submitted as an AJAX request. Since you're not passing local: false to the form_with call, there must be a configuration set to use AJAX form submissions by default.

    From the docs,

    :local - By default form submits via typical HTTP requests. Enable remote and unobtrusive XHRs submits with local: false. Remote forms may be enabled by default by setting config.action_view.form_with_generates_remote_forms = true.

    Pass local: true to submit the request via a normal HTTP request.

    <%= form_with model: @occasion, local: true do |form| %>
      <%#= ... %>
    <% end %>