Rails error messages not showing? - ruby-on-rails

I'm new to rails...but I'm trying to do an app on my own to "practice" what I've learned.
I have a new form with model validations, but the error messages aren't showing. Here is what I have:
seed.rb (Model)
class Seed < ApplicationRecord
validates :name, presence: true
validates :category, presence: true
validates :latin, presence: true
validates :maturity, presence: true
validates :sun, presence: true
validates :sow, presence: true
validates :cycle, presence: true
validates :description, presence: true, length: { minimum: 5, maximum: 500 }
mount_uploader :seedimage, SeedImageUploader
end
seed_controller.rb (Controller)
class SeedsController < ApplicationController
def index
#seeds = Seed.all
end
def new
#seed = Seed.new
end
def create
#seed = Seed.new(seed_params)
if #seed.save
redirect_to seeds_path
else
render 'new'
end
end
def edit
end
def update
#seed = Seed.find(params[:id])
if #seed.update(seed_params)
redirect_to #seed
else
render 'edit'
end
end
def show
#seed = Seed.find(params[:id])
end
def destroy
#seed = Seed.find(params[:id])
#seed.destroy
redirect_to seeds_path
end
def seed_params
params.require(:seed).permit(:name, :category, :latin, :maturity, :sun, :sow, :cycle, :description, :seedimage)
end
end
_form.html.erb (Form for 'New') (new.html.erb just has <% render 'form' %>
<%= form_with model: #seed, class: "form-horizontal" do |f| %>
<% if #seed.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#seed.errors.count, "error") %> prohibited
this seed from being saved:
</h2>
<ul>
<% #seed.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: "form-control", placeholder: "Seed Name" %>
</div>
<div class="form-group">
<%= f.label :category %>
<%= f.text_field :category, class: "form-control", placeholder: "Category: 'beans'" %>
</div>
<div class="control-label">
<%= f.label :latin %>
<%= f.text_field :latin, class: "form-control", placeholder: "Latin Name" %>
</div>
<div class="form-group">
<%= f.label :maturity %>
<%= f.number_field :maturity, class: "form-control", placeholder: "Maturity Time" %>
</div>
<div class="form-group">
<%= f.label :sun %>
<%= f.select(:sun, options_for_select([['Full Sun'], ['Partial Sun'], ['Full Shade']]), {}, { class: "custom-select"}) %>
</div>
<div class="form-group">
<%= f.label :sow %>
<%= f.text_field :sow, class: "form-control", placeholder: "Plant Indoors/Sow Outdoors/etc.." %>
</div>
<div class="form-group">
<%= f.label :cycle %>
<%= f.text_field :cycle, class: "form-control", placeholder: "Annual/Perennial/etc.." %>
</div>
<div class="form-group">
<%= f.label :description %>
<%= f.text_area :description, size: "60x12", class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :seedimage %>
<%= f.file_field :seedimage, class: "form-control" %>
</div>
<div class="form-group">
<%= f.submit "Create", class: "btn btn-primary btn-lg" %>
</div>
<% end %>
I'm a bit confused why this doesn't work? Right now when I hit the create button it flashes, but no error messages. I can CONFIRM that the model is using the validations because if I try to do a Seed.create() and check messages against that it doesn't indeed work....so I'm a bit confused?
From what I can tell the .any? isn't happening, since if I do a ! to that statement it'll at least display 0 messages.

You are not seeing any error messages because all the forms generated by form_with tag are remote: true by default and send xhr(ajax) requests to the server. If you want to see the error messages, as of your current setup, you have to add local: true wich makes the submission normal.
Replacing
<%= form_with model: #seed, class: "form-horizontal" do |f| %>
with
<%= form_with model: #seed, local: true, class: "form-horizontal" do |f| %>
will do the trick. Hope this will help.

Related

Using validations and pluralize in views to show errors count for forms rails 7

i am trying to display a message for whenever someone does not fill the form completely and press the submit button!
Example: when someone clicks the submit button without filling the Name and Email field in the form, it should display
2 Errors Prohibited from submitting the form!
. Name can't be blank
. Email can't be blank
but it is not being displayed whenever we submit the form with empty fields
can someone explain me the reason why it is not working?
Orders_controller.rb
class OrdersController < ApplicationController
# GET to /orders/new
def new
#order = Order.new
end
# POST to /orders
def create
#order = Order.new(order_params)
respond_to do |format|
if #order.save!
format.html{ redirect_to root_url, notice: "Order Succesfully Submitted!" }
else
format.html{ render :new, status: :unprocessable_entity }
end
end
end
private
def order_params
params.require(:order).permit(:first_name, :last_name, :phone_number, :email, :paper_size, :color, :paper_style, :quantity, :description, files: [] )
end
end
_form.html.erb (i already rendered the partial in new.html.erb by <%= render 'form', order: #order%>
<div class="container">
<h1 class="text-center">Order From Home!</h1>
<div class="row">
<div class="col-md-4 col-md-offset-4">
<%= form_with(model: order) do |f| %>
<% if order.errors.any? %>
<div style="color: red">
<h3><%= pluralize(order.errors.count,"errors")%> Prohibited from submitting the form! <br/>
All Fields Are Required!</h3>
<ul>
<% order.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.label :first_name%>
<%= f.text_field :first_name, class:"form-control" %><br/>
<%= f.label :last_name %>
<%= f.text_field :last_name, class:"form-control" %><br/>
<%= f.label :phone_number %>
<%= f.text_field :phone_number, class:"form-control" %><br/>
<%= f.label :email %>
<%= f.text_field :email, class:"form-control" %><br/>
<%= f.label :files %>
<%= f.file_field :files, multiple: true %><br/>
<%= f.label :paper_size %>
<%= f.select :paper_size, ['A4', 'B4'], { prompt: 'Select' }, class:'form-select' %><br/>
<%= f.label :color %>
<%= f.select :color, ['Black & White', 'Color'], { prompt: 'Select' }, class:'form-select' %><br/>
<%= f.label :paper_style %>
<%= f.select :paper_style, ['Black to Back', 'Side to Side'], { prompt: 'Select' }, class:'form-select' %><br/>
<%= f.label :quantity %>
<%= f.number_field :quantity, class:'form-control' %><br/>
<%= f.label :description %>
<%= f.text_area :description, class:"form-control" %><br/>
<div class="btn-order">
<%= f.submit %>
</div>
<% end %>
</div>
</div>
</div>
#order.save! raises validation errors. You don't need bang method if you want to render such errors, just use #order.save instead
form_with sends XHR request. If you need to render something, you can disable Turbo for this form
<%= form_with(model: order, data: { turbo: false }) do |f| %>

Failed to save the new associated seo_setting on has_one association

I have 2 models:
class Page < ApplicationRecord
enum page_type: STATIC_PAGE_TYPES, _suffix: true
has_one :seo_setting
accepts_nested_attributes_for :seo_setting, update_only: true
validates :title, :subtitle, length: { maximum: 50 }
validates :page_type, uniqueness: true
def to_param
"#{id}-#{page_type}".parameterize
end
end
and
class SeoSetting < ApplicationRecord
mount_uploader :og_image, SeoSettingsOgImageUploader
belongs_to :page
validates :seo_title, :seo_description, :og_title, :og_description, :og_image, presence: true
end
My Page objects are created from the seeds.rb file, and when I want to edit them, I get an error: Failed to save the new associated seo_setting.
In the form I have this:
<div class="card-body">
<%= form_for([:admin, #page]) do |f| %>
<%= render 'shared/admin/error-messages', object: #page %>
<div class="form-group">
<%= f.label :title, t('admin.shared.title') %>
<%= f.text_field :title, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :subtitle, t('admin.shared.subtitle') %>
<%= f.text_field :subtitle, class: 'form-control' %>
</div>
<h3>SEO Settings</h3>
<%= f.fields_for :seo_setting, f.object.seo_setting ||= f.object.build_seo_setting do |form| %>
<div class="form-group">
<%= form.label :seo_title, t('admin.shared.seo_title') %>
<%= form.text_field :seo_title, class: 'form-control' %>
</div>
<div class="form-group">
<%= form.label :seo_description, t('admin.shared.seo_description') %>
<%= form.text_area :seo_description, class: 'form-control' %>
</div>
<div class="form-group">
<%= form.label :og_title, t('admin.shared.og_title') %>
<%= form.text_field :og_title, class: 'form-control' %>
</div>
<div class="form-group">
<%= form.label :og_description, t('admin.shared.og_description') %>
<%= form.text_area :og_description, class: 'form-control' %>
</div>
<div class="form-group">
<%= form.label :og_image, t('admin.shared.og_image') %>
<div class="row">
<div class="col-lg-12">
<%= image_tag(form.object.og_image.url, style: 'width: 100px') if form.object.og_image? %>
</div>
</div>
<%= form.file_field :og_image %>
<%= form.hidden_field :og_image_cache %>
</div>
<% end %>
<div class="form-group">
<%= f.submit t('admin.actions.submit'), class: 'btn btn-success' %>
<%= link_to t('admin.actions.cancel'), admin_page_path(#page) , class: 'btn btn-default' %>
</div>
<% end %>
</div>
If I remove validations from my SeoSetting model, everything is working. It seems Rails doesn't like this part: f.object.build_seo_setting, because it creates a record in my database. Any ideas of how can I solve this issue? Thanks ahead.
Just had to change this line:
<%= f.fields_for :seo_setting, f.object.seo_setting ||= f.object.build_seo_setting do |form| %>
for this one:
<%= f.fields_for :seo_setting, #page.seo_setting.nil? ? #page.build_seo_setting : #page.seo_setting do |form| %>
Looks as if the problem lies here:
accepts_nested_attributes_for :seo_setting, update_only: true
in that you only allow the updating of the seo_setting on update.
Then, when you use this code:
f.object.seo_setting ||= f.object.build_seo_setting
You're falling back to a new seo_setting if the associated object is missing.
For this to work, you'll need to either remove the update_only: true, or only render the fields for the association if the seo_setting already exists.
Accepted answer, a conditional inside fields_for line, by OP, works also with polymorphic association and nested form (fields_for). Thnx Alex.

How to Force the User to Complete the Whole Form?

I am creating a Sing Up form. I need the user to complete every field of the form, but the rails only blocks the creation when there is no password. What I have to do to force the user to complete the whole form before submiting?
Here's my form code:
<%= form_for(user) do |f| %>
<% if user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% user.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :first_name %>
<%= f.text_field :first_name %>
</div>
<div class="field">
<%= f.label :last_name %>
<%= f.text_field :last_name %>
</div>
<div class="field">
<%= f.label :email %>
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password %>
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
</div>
<div class="field">
<%= f.label :fav_team, "Favorite Team" %>
<%= collection_select(:user, :fav_team, League.order(:name), :id, :name, {:include_blank => "Select a League"}, { :id => "leagues_select"}) %>
<%= grouped_collection_select(:user, :fav_team, League.order(:name), :teams, :name, :id, :name, {:include_blank => true}, {}) %>
</div>
<div class="field">
<%= f.label :net_worth, "Net Worth (USD)" %>
<%= f.text_field :net_worth, :readonly => true, :value => "100" %>
</div>
<div class="field">
<%= f.label :country %>
<%= f.select :country, options_for_Countrys, :include_blank => true %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
You have to write validations in your models to make sure the data is valid and present.
In your case you have to do something like this
class User < ApplicationRecord
validates :first_name, presence: true, length: { maximum: 50 }
validates :last_name, presence: true, length: { maximum: 50 }
end
You can check here for more information

Showing :name from signup form in profiles form using Devise in rails app

I need my App to be able to display :name from the sign up form in the profiles/new _form is that possible? and how?
When my User sign up for an account via Devise they sign up by inserting :name, emailand password. Like seen in the code below:
<div class="row img-back">
<div class="col-md-6 col-md-offset-3 text-center">
<div class="well sign-up-form">
<h2>Ný skráning</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="field form-group">
<%= f.label :Nafn_fyrirtækis_stofnunar %><br />
<%= f.text_field :name, autofocus: true, class: 'form-control' %>
</div>
<div class="field form-group">
<%= f.label :tölvu_póstfang %><br />
<%= f.email_field :email, class: 'form-control' %>
</div>
<div class="field form-group">
<%= f.label :Lykilorð %>
<% if #minimum_password_length %>
<em>(Minnst <%= #minimum_password_length %> stafir )</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off", class: 'form-control' %>
</div>
<div class="field form-group">
<%= f.label :Staðfesting_lykilorðs %><br />
<%= f.password_field :password_confirmation, autocomplete: "off", class: 'form-control' %>
</div>
<div class="actions">
<%= f.submit "Ný skrá", class: 'btn btn-success' %>
</div>
<% end %>
<%= render "devise/shared/links" %>
</div>
After Sign up the user is directed to the views/profiles/new.html.erb with this method in registrations_controller.rb
def after_sign_up_path_for(resource)
new_user_profile_path(current_user)
end
And in the views/profiles/new.html.erb the user fills in a _form.html.erb partial to finish its profile and register all the information the app needs to work for the user.
this is the _form.html.erb
%= form_for #profile, url: user_profile_path, :html => { :multipart => true } do |f| %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :avatar %>
<%= f.file_field :avatar, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :staff %>
<%= f.number_field :staff, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :building_size %>
<%= f.number_field :building_size, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :address %>
<%= f.text_field :address, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :postalcode %>
<%= f.text_field :postalcode, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :website%>
<%= f.text_field :website, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :contact_person %>
<%= f.text_field :contact_person, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :contact_email %>
<%= f.email_field :contact_email, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :phone_number %>
<%= f.text_field :phone_number, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :buisness_type %>
<%= f.select :buisness_type,['Þjónusta', 'Ráðgjöf', 'Verlsun', 'Stofnun', 'Annað'], class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :description %>
<%= f.text_area :description, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.submit "Update Profile", class: 'btn btn-primary' %>
</div>
<% end %>
My profile.rb belongs_to :userand my user.rb model has_one :profile
EDIT according to jsw324 answer
Here is the profiles_controller.rb
class ProfilesController < ApplicationController
before_action :authenticate_user!
#before_action :only_current_user
def new
#form where a user can fill put their pwn profile.
#user = User.find(params[:user_id]) # Finnur hver er userinn sem er loggaður inn, reaching in to the url and grabbs user.
#profile = Profile.new
#profile.name = current_user.name
end
def show
#user = User.find(params[:user_id])
##profile = #user.profile
#profile.name = current_user.name
end
def create
#user = User.find(params[:user_id])
#profile = #user.build_profile(profile_params)
#Lecture 159 User show action next :))))
if #profile.save
flash[:success] = "Profile updated"
redirect_to user_path(params[:user_id]) #fer á user/show.html.erb
else
render action: :new
end
end
def edit
#user = User.find(params[:user_id])
#profile = #user.profile
end
def update
#user = User.find(params[:user_id])
#profile = #user.profile
if #profile.update_attributes(profile_params)
flash[:success] = "Profile Updated!"
redirect_to user_path(params[:user_id])
else
render action :edit
end
end
private
def profile_params
params.require(:profile).permit(:name, :staff, :address, :postalcode, :website, :contact_person, :contact_email, :phone_number, :buisness_type, :description, :building_size, :avatar)
end
def only_current_user
#user = User.find(params[:user_id])
redirect_to(root_url) unless #user == current_user
end
And I edited this line in the views/profiles/_form.html.erb
<%= form_for #profile, url: user_profile_path, :html => { :multipart => true } do |f| %>
<div class="row">
<div class="container">
<div class="col-md-6">
<div class="form-group">
<%= f.label :Name %>
<%= f.name %>
</div>
Now I get this Error: undefined methodname' for #`
Ahh. You need to handle that in the controller. Something like #profiles.name = current_user.name.
I'm not sure I understand but to display the name you can just use <%= current_user.name %> wherever you need it.

Rails trying to create a user when updating user details

I'm learning rails and building an authentication system using guides from around the web and following railscasts tutorials.
I've come to a stand still at the moment and need a bit of assistance if possible.
When ever I try to edit the user profile, I get an error message which tells me that it can't create an account due to fields such as email and username already being taken.
Looking around it seems it's related to how my edit form is being submitted, but I can't solve it!
Any help would be appreciated.
Users_controller.rb
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
edit.html.erb
<%= form_for :user, url: '/users' do |f| %>
<form class="m-t" role="form" action="#">
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control', autocomplete: "off" %>
</div>
<div class="form-group">
<%= f.label :user_type %>
<%= f.select(:user_type, ['Admin', 'Technical', 'Accounts'], {}, { :class => 'form-control' }) %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.text_field :email, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :telephone %>
<%= f.text_field :telephone, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :mobile %>
<%= f.text_field :mobile, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :user_name %>
<%= f.text_field :user_name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :company_admin%>
<%= f.check_box :company_admin, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :user_admin %>
<%= f.check_box :user_admin, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :emergency_contact %>
<%= f.check_box :emergency_contact, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.submit "Submit", class: "btn btn-primary block full-width m-b" %>
</div>
</form>
<% end %>
Rails Log
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = 'emailaddress#gmail.com' LIMIT 1
User Exists (0.1ms) SELECT 1 AS one FROM "users" WHERE "users"."user_name" = 'AUserName' LIMIT 1
user.rb
class User < ActiveRecord::Base
has_secure_password
validates :name, presence: { message: "Please enter your name." }
validates_uniqueness_of :email, presence: { message: "Please enter your email address." }
validates_format_of :email, with: /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z] {2,})\z/i, message: "Please enter a valid email address.", allow_blank: true
validates :telephone, presence: { message: "Please enter your phone number." }
validates :mobile, presence: { message: "Please enter your mobile number." }
validates_uniqueness_of :user_name, presence: { message: "Please enter your user name." }
validates_confirmation_of :password, presence: { message: "Please enter your password" }, allow_nil: true
before_create { generate_token(:auth_token) }
def generate_token(column)
begin
self[column] = SecureRandom.urlsafe_base64
end while User.exists?(column => self[column])
end
def send_password_reset
generate_token(:password_reset_token)
self.password_reset_sent_at = Time.zone.now
save!
UserMailer.password_reset(self).deliver
end
end
Wait I'm wrong on the validation. Just spotted it.
<%= form_for :user, url: '/users' do |f| %>
This won't use the #user object, which means rails thinks you're trying to create a user.
Switch it to
<%= form_for #user do |f| %>
Rails will also infer the correct place to post to so you won't need the url option anymore.

Resources