Rails model validation not working - validation

model:
validates :name, :presence => true
validates :year, :presence => true
validates :description, :presence => true
when submitting the form containing these fields, leaving the text boxes blank on purpose, instead of getting the Rails error messaging, I get the following exception thrown:
NoMethodError
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each
Any thoughts on why this may occur would be greatly appreciated.

A stab in the dark would be that its not your validations throwing the error message. My first instinct is that its the error view code (if you are looping through the errors the nil is possibly in there). Its also possible its an error in the controller but I would have to see the first couple lines of the backtrace to make a more informed guess.

Related

Method missing in User model, Rails 4.1

This should be easy but I'm obviously missing something. Working through a testing exercise, and attempting to create a method on the User model. Seems like it should be incredibly straightforward, but Rails is throwing method missing whenever I attempt to access the method.
Here's the code for the file app/models/user.rb:
class User < ActiveRecord::Base
has_secure_password
validates :email, presence: true, uniqueness: true
def administrator?
end
end
At this point I'm working through TDD process, and only attempting to satisfy the test exception by creating the method (I'll add code for the administrator? method later). Here's the line from the spec:
expect(admin.administrator?).to be_true
And the output from the test:
1) User management adds a new user
Failure/Error: expect(admin.administrator?).to be_true
expected to respond to `true?`
However, I can't seem to access the freaking method! Whenever I call the #administrator? method on an object of the User class I get:
NoMethodError: undefined method `administrator?' for #<User:0x007f9ac6929358>
Here's the pry response to 'ls -M' when I'm in the User class, showing the methods available:
User#methods: administrator password password_confirmation
Here's the output from a pry console session:
[73] pry(User):1> admin = User.first
User Load (0.2ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
=> #<User id: 1, email: "test#yahoo.com", password_digest: "secret123", created_at: "2015-06-25 17:33:25", updated_at: "2015-06-25 17:33:25", admin: true, firstname: nil, lastname: nil>
[74] pry(User):1> admin.valid?
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE ("users"."email" = 'test#yahoo.com' AND "users"."id" != 1) LIMIT 1
=> true
[75] pry(User):1> admin.instance_of?(User)
=> true
[76] pry(User):1> admin.administrator?
NoMethodError: undefined method `administrator?' for #<User:0x007f9ac6929358>
from /Users/me/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activemodel-4.1.1/lib/active_model/attribute_methods.rb:435:in `method_missing'
I've tried defining the method as self.administrator as well, with the same results. I went back and looked at the model methods defined in the Rails Tutorial, and I can't see anything about Hartl's model that helps me understand why my method isn't working.
Any help would be appreciated! I'm missing something basic here it seems...
**** EDIT/UPDATE ****
After getting a response about how to return the boolean :admin column from the user object I realized that it's worth clarifying the real question. The real issue I was trying to understand isn't so much whether the administrator? method is the best way to determine whether a given user is an admin or not (as #sajinmp very helpfully points out below, the object will respond to admin? because of the corresponding column in the database).
My real question/frustration was with why I couldn't get the object to respond to that or any other methods created in the model.
If all you are doing in the method is to check whether a user is an admin or not you do not need such a specific method. Since in your user model the administrator is represented by admin simply calling admin? is enough.
current_user.admin (<admin.admin> in this case)
will answer your call. But when admin is nil this will be a problem so it is better to use
admin.try(:admin)
This will not throw an error even if admin is nil.
I restarted the Rails server, and that seemed to fix it. After cycling the server and starting a new console session, the user object now responds to the methods in user.rb.
Should have done that sooner (DUH!), but I'd assumed that it wouldn't be necessary. Within the console session I could use reload! and then the Pry show-source method would confirm that the methods were appearing in the console as written. I didn't think that the console relied on the server, but I must be wrong..?
Appreciate any confirmation on this.

Why can't I check ActiveRecord validations in the console?

I'm learning RoR at the moment, and I think I must be misunderstanding something.
I have an ActiveRecord class call User, with simple validations on :name and :email such as presence: true, length: { maximum: 15 }, etc. I thought I'd check the validations in the console. I go into rails console (development env), and create a new instance with a name that is too long, such as
user_instance = User.new (name:"aaaaabbbbbcccccddddd", email:"").
The validation doesn't throw up any errors. When I try user_instance.save, the record won't write to the DB, so it's obviously working fine at that stage. What am I doing wrong?
When you want to get an exception raised on record saving, use save! instead of save (same with update/update!, create/create!).
With save you won't have an exception raised if there are validation errors, it will just return false. You can also check if there are errors on an instance with user_instance.valid? and get the errors with user_instance.errors.
See When Does Validation Happen?.
the validation won't throw errors if you try to set invalid data on your model, however the save will fail.
if you wanna check out if the validation is working correctly, just check user.valid? and it should return false
after calling valid?, you can check user.errors for the specific errors set on your model.

Odd behaviour when saving instances in Ruby DataMapper

having just started to look at DataMapper for Ruby ORM I've run into an issue that confuses me to no end.
The default behaviour when saving instances in DataMapper (through DataMapper::Resource.save) is, as far as I understand, to silently fail, return false from the save method and collect any errors in the errors collection. So far so good, this works as expected. The issue I see is with natural primary keys, where setting duplicate ones will throw an exception instead of silently returning false from the save method, blatantly disregarding the current setting of raise_on_save_failure. Consider the following snippet;
require 'data_mapper'
class Thing
include DataMapper::Resource
property :name , String, :key=> true
property :description, String, length: 2..5
end
DataMapper.setup :default, "sqlite:memory"
DataMapper.finalize
DataMapper.auto_migrate!
#Create a thing and have it properly silently fail saving
t1=Thing.new(:name=>"n1",:description=>"verylongdescription" )
t1.save #ok
puts("t1 is saved:"+t1.saved?.to_s)
t1.errors.each do |e|
puts e
end
#Create two things with the same key, and fail miserably in silently failing the second save...
t1=Thing.new(:name=>"n1",:description=>"ok" )
t2=Thing.new(:name=>"n1",:description=>"ok" )
t1.save #ok
t2.save #not ok, raises Exception event though it shouldn't?
puts("t2 is saved:"+t1.saved?.to_s)
t2.errors.each do |e|
puts e
end
The first save, on an instance failing a validation rule for the :description property behaves as expected. The third save, of an instance with duplicate keys, however does not, since it raises an execption instead of nicely just returning false.
Why is this? It is obviously possible to work around, but it doesn't feel very clear. Is the case that the silent behaviour will only apply to validation errors in the DataMapper layer, and any hard errors from the underlying datastore will be propagated as exceptions to the caller?
Thanks!
As another user pointed out in a comment, this happens because setting raise_on_save_failure to false doesn't mean that no exceptions will occur. It will always return false (with no exceptions) when validation errors occur.
Database errors will blow up, as you noticed, in the form of an exception. Such errors could happen due to a large number of factors (the connection failed, no disk space), including mundane ones like a duplicate key. DataMapper can't know whether the object you're trying to save possesses a duplicate key, so it just validates it and sends to the database, where the error actually occurs.

Rails3 RegexpError (regular expression too big: /password|password_confirmation)

I'm using Rails 3.0.0 with Authlogic 2.1.6 and from time to time I'm getting this error message:
RegexpError (regular expression too big:
/password|password_confirmation....
It results with internal server error and I have to restart my server to get it work again. Anyone know how to avoid this issue?
It's sounding as though the :length of the password and/or password_confirmation fields is too long. Do a validation first: validates_length_of :password … to keep too large of passwords from being entered.

Paperclip Giving Required field error

in my project i have form in that there is file field to upload file and I am using paperclip gem for that and add only validation 'validates_attachment_content_type' but when i submit a form without any file selected it gives error of 'validates_attachment_content_type',
it should not give any error as i am not add validation 'validates_attachment_presence'. I am very confused for what it giving error of 'validates_attachment_content_type' when i submit a form without any file uploaded.
after googling for the same i got answer for this prob just we have to add :allow_nil => true in validation
for eg.
validates_attachment_content_type :logo, :content_type => ['image/jpeg','image/png','image /jpg','image/gif'],
:message=>"Image file must be of .jpeg,'.jpg', '.gif' or .png type",:allow_nil => true
:allow_nil => true
is realy work great and very easy to test.YOu can put it after your validation.

Resources