object.valid? returns false but object.errors.full_messages is empty
I had the same problem. At first I had such code in my model:
before_validation :set_some_param
def set_some_param
self.some_param = some_value
end
After I changed this to:
before_validation :set_some_param
def set_some_param
self.some_param = some_value
true
end
I could see my errors.
Maybe you have something simular in your code?
Valid is false but errors empty
Every time you do current_user.contact
you make a new contact object. So, what you're doing is this:
#make a new contact object and run validations on it
current_user.contact.valid?
#make a new contact object, which hasn't had validation run on it, then see if it has errors
current_user.contact.errors.count
Try this:
contact = current_user.contact
contact.valid?
contact.errors.count
Record does not save with ROLLBACK, but errors object is empty
The most likely cause seems to be a failed validation on @classification.global_filters
. You can try also inspecting those errors with @classification.global_filters.map{|f| f.errors.full_messages}
.
To deal with the actual problem at hand, you can look into using http://apidock.com/rails/ActiveRecord/Validations/ClassMethods/validates_associated or write your own custom validation in the Classification model to check for any errors in its global filters.
Another tool to help with these cases is the gem for https://github.com/charliesome/better_errors. If you add it in the development environment, you can run arbitrary code to inspect the objects at certain parts of your code whenever an error is triggered. You can simply call @classification.save!
to trigger an error if it fails, and then you can inspect the object in detail on the better errors page. You can also add arbitrary "breakpoints" by just raising any exception.
How do I use a hidden_field_tag to help create a valid object in Ruby on Rails?
With help from Maxence, I discovered I need to use f.hidden_field
versus hidden_field_tag
so I changed the views/shared/_comment_form.html.erb to the following:
<%= form_with(model: @comment) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<center>
<div class="field">
<%= f.text_area(:content, placeholder: "Comment on this prayer...") %>
</div>
<div><%= f.hidden_field :user_id, value: @user.id %></div>
<div><%= f.hidden_field :prayer_id, value: prayer_id %></div>
<%= f.submit "Comment", class: "btn btn-primary" %>
</center>
<% end %>
In rails, how can I find out what caused a .save() to fail, other than validation errors?
Check all your callbacks.
I had a problem like this where I had and "after_validate" method that was failing after I had made a bunch of changes to the model. The model was valid but the "after_validate" was returning false, so if I used model.valid
it said true, but then if I saved it gave me validation errors (passed through from the after_validate callback). It was weird.
Look at the application trace and you should be able to see what line of code is raising the exception.
Displaying only 1 error per field in a form
You can do that very easy with this line:
<%= @object.errors.full_messages.first if @object.errors.any? %>
Just replace with your object instance. If you want to use with just one field then there is this method
http://api.rubyonrails.org/classes/ActiveModel/Errors.html#method-i-full_messages_for:
object.errors.full_messages_for(:email)
This will get you specific error for single field
EDIT:
if you have a lot of fields:
<% @object.errors.each do |attr, msg| %>
<%= "#{attr} #{msg}" if @object.errors[attr].first == msg %>
<% end %>
Validation error in test but error array is empty
The problem was that I used mocha's Post.any_instance.stubs(:valid?).returns(false)
in a test that was executed before my failing test.
Apparently, you have to restore the original behavior before proceeding with other tests by calling Post.any_instance.unstub(:valid?)
.
Rails not generating validation fail messages
I managed to get to the bottom of my problem. In the controller I was using:
redirect_to :action => :edit
I should have been using:
render :action => :edit
By using redirect_to I was hitting the edit action within the controller which was then getting a new camera object from the database rather than preserving the current camera object from the update action.
Rails 5 - Displaying error messages
The issue was that in order to make the @user
instance variable available to the view, you need to render rather than redirect.
When you redirect, you're sending a response to the user that says, "Hit me up again". When the subsequent request comes in, the action gets executed a second time. The @user
instance variable was available the first time the action was executed, but based on the logic in the action, doesn't get populated with errors on the second time (why would it).
See How are Rails instance variables passed to views?.
The issue could be at any of the following steps:
- The request may not be getting routed to the controller you expect. Try looking at the server logs. When you start your server with
rails server
orrails s
in the console, that window will show all incoming requests, and it'll show the controller + action that get hit. For example:
Example from my test app:
code/blog [master●] » rails s
=> Booting Puma
=> Rails 5.0.2 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.8.2 (ruby 2.4.1-p111), codename: Sassy Salamander
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://localhost:3000
Use Ctrl-C to stop
Started GET "/" for ::1 at 2017-04-19 17:55:42 -0700
ActiveRecord::SchemaMigration Load (0.4ms) SELECT "schema_migrations".* FROM "schema_migrations"
Processing by UncategorizedPagesController#home as HTML
Rendering uncategorized_pages/home.html.erb within layouts/application
Rendered uncategorized_pages/home.html.erb within layouts/application (1.4ms)
Rendered partials/_navbar.html.erb (0.8ms)
Completed 200 OK in 293ms (Views: 291.3ms | ActiveRecord: 0.0ms)
Here you can see that the request is GET /
, and it hits the home
action of UncategorizedPagesController
. To be doubly sure, you could add a puts "hits this action"
in your controller action, and look for "hits this action" in your server logs.
The form(s) may not be sending the payload you expect them to be sending to the server. Try checking the
params
hash in your controller. As the link explains, theparams
hash will contain the data you submitted in your form. Ie.params[:email]
might befoo@bar.com
in your controller. You can test this by addingputs params
to your controller action and checking the server logs after you hit the corresponding route.The validations may not be behaving as you expect them to. To test this, try using the console (in sandbox mode so it doesn't mess with your actual database) like so:
Console output:
$ rails console --sandbox
>> user = User.new(name: "", email: "mhartl@example.com")
>> user.valid?
=> false
>> user.errors.full_messages
=> ["Name can't be blank"]
You should also use unit tests to make sure your validations work as expected. See below for an example from the Rails Tutorial
require 'test_helper'
class UserTest < ActiveSupport::TestCase
def setup
@user = User.new(name: "Example User", email: "user@example.com")
end
test "should be valid" do
assert @user.valid?
end
test "name should be present" do
@user.name = ""
assert_not @user.valid?
end
test "email should be present" do
@user.email = " "
assert_not @user.valid?
end
end
- You may not be trigging validation to happen. From the official RailsGuide:
The following methods trigger validations, and will save the object to
the database only if the object is valid:
- create
- create!
- save
- save!
- update
- update!
The bang versions (e.g.
save!) raise an exception if the record is invalid. The non-bang
versions don't: save and update return false, and create just returns
the object.
Your controller logic may not be sending the user with errors back to the view. To test this, print out the full
@user
in one of thenew.html.erb
files using any of the approaches mentioned in the RailsGuide.debug(@user)
is one option.You may not be referencing the right file in your attempt to render the
_errors.html.erb
partial. To test this, try to render the partial with just ahello world
.You may not be passing in the object to the partial properly. To test this, try logging out your object from the view using any of the approaches mentioned in the RailsGuide.
debug(object)
is one option.
It seems that you are doing it properly though. From the docs:
If you're not going to be using any of the options like collections or layouts, you can also use the short-hand defaults of render to render partials. Examples:
# Instead of <%= render partial: "account", locals: { account: @buyer } %>
<%= render "account", account: @buyer %>
Related Topics
Ruby Strftime: Month Without Leading Zero
How to Filter an Array of Hashes to Get Only the Keys in Another Array
How to Make Rails 3 Assets Precompile Faster
Redirect the "Puts" Command Output to a Log File
All Possible Permutations of a Given String
Checking If a Method Is Defined on the Class
How to Use Nokogiri to Parse an Xml File
How to Dynamically Define a Class Method Which Will Refer to a Local Variable Outside
Rails Scope Find with Current User
Get Substring After the First = Symbol in Ruby
Why Should I Use Rspec or Shoulda with Rails
Accessing Ruby Class Variables with Class_Eval and Instance_Eval
App Pushed to Heroku Still Shows Standard Index Page
Sorting: Sort Array Based on Multiple Conditions in Ruby
How to Solve the Update Bundler Warning in Rails When Deploying to Heroku
How to Use Rails and Paperclip to Store Photos on Google Cloud Storage