Returning true or error message in Ruby
I would say that methods that return different types (e.g. boolean vs. string vs. numbers) under different circumstances are a bad practice.
If you have some sort of test method that wants to return details of why the test has not passed then you can return a pair of values (an Array
) as follows:
def test(x)
if x == 1
return true, "x is fine"
else
return false, "Error: x is not equal to one."
end
end
and then write the section of your controller code as:
valid, message = @item.save_image(params[:attachment][:file])
if !valid
flash[:notice] = message
redirect_to(new_item_url) and return
end
If you're talking about a save_image
method that will succeed the majority of the time but may fail and you want to indicate this failure and the reason then I would use exceptions e.g.
def save_image(file)
raise "No file was specified for saving" if file.nil?
# carry on trying to save image
end
and then your controller code would be along the lines of:
begin
result = @item.save_image(params[:attachment][:file])
rescue Exception => ex
flash[:notice] = ex.message
redirect_to(new_item_url) and return
end
How to return error messages in rails
You should return the errors which occurred (if any) while creating the object. Your object is an instance of Spaceship::Tunes::Application, so you should be searching for whether this class defines any instance methods which return validation errors.
I am not familiar with this class, but after a quick look into it's documentation I do not see that it even has any validations in create method.
So you can just return a custom error message if by any chance the object creation failed.
As to
what status should I return with the error in this case?
Take a look into the list of status codes and pick suitable one (I think 400 (Bad Request) would do).
Ruby: How do I return a boolean value if the correct error is raised?
When an exception has been raised but not yet handled (in rescue, ensure, at_exit and END blocks) the global variable $! will contain the current exception and $@ contains the current exception’s backtrace.
Do as below (using inline rescue
way):
2.0.0-p0 :001 > [1, 2, 3].first("two")
TypeError: no implicit conversion of String into Integer
from (irb):1:in 'first'
from (irb):1
from /home/kirti/.rvm/rubies/ruby-2.0.0-p0/bin/irb:16:in '<main>'
2.0.0-p0 :002 > [1, 2, 3].first("two") rescue $!.class == TypeError
=> true
2.0.0-p0 :003 > [1, 2, 3]['a'] rescue $!.class == TypeError
=> true
2.0.0-p0 :004 > [1, 2, 3]['a']
TypeError: no implicit conversion of String into Integer
from (irb):4:in '[]'
from (irb):4
from /home/kirti/.rvm/rubies/ruby-2.0.0-p0/bin/irb:16:in '<main>'
2.0.0-p0 :005 > 1/0 rescue $!.class == TypeError
=> false
2.0.0-p0 :006 >
TypeError
Raised when encountering an object that is not of the expected type.
[1, 2, 3].first("two")
raises the exception:
TypeError: no implicit conversion of String into Integer
In your case you could write as below :
some_method(arg) rescue $!.class == TypeError
ActiveRecord valid? method returning true even with errors present
You should be adding the method as a validator, once the validator is done, you can check valid?
Remove the before_create and then add:
validate :allow_unique_only
http://guides.rubyonrails.org/active_record_validations.html#custom-methods
How to check and return string or return false and exit if statement
parsed.dig('error').to_s.downcase.include?('email does not exist')
to_s
converts nil
to ''
. No need for downcase!
because you don't need to mutate the original object and because it returns nil
if no changes were made; just use downcase
.
Note that your example uses symbolized keys and your code uses stringified keys, so it'll never match:
parsed = {error: "Email does not exist"} # key is symbolized
parsed.dig('error').to_s.downcase.include?('email does not exist') # key is stringified
=> false
parsed = {error: "Email does not exist"} # key is symbolized
parsed.dig(:error).to_s.downcase.include?('email does not exist') # key is symbolized
=> true
Since you're using Rails, you can make your life a little easier with indifferent access. This allows hash keys to be accessed by string or by symbol:
parsed.with_indifferent_access.dig('error').to_s.downcase.include?('email does not exist')
=> true
parsed.with_indifferent_access.dig(:error).to_s.downcase.include?('email does not exist')
=> true
Using this gives you some flexibility.
Rails returning validation error message from model method
save!
throws an exception, while save
just returns true
or false
. Just remove the exclamation mark.
How to return a value or conditionally raise an error in Ruby?
I wouldn't strain to write a one-liner, but you can use tap
if you absolutely must:
def data
(@data ||= SNL.get_list(name)).tap { |d| d.success? or raise StandardError.new(d.inspect) }
end
Also with short-circuited logic:
def data
(@data ||= SNL.get_list(name)).success? && @data or
raise StandardError.new(@data.inspect) }
end
Related Topics
How to Use a Named Scope in My Model Against an Array of Items
What Is the Most Ruby-Ish Way of Accessing Nested Hash Values at Arbitrary Depths
How to Find All Modules and Classes Within a Module, Recursively
Sign Out Specific User with Devise in Rails
Get an Array from a Rails Form
Recovering from a Broken Tcp Socket in Ruby When in Gets()
Open-Uri Returning Ascii-8Bit from Webpage Encoded in Iso-8859
Wicked_Pdf: Footer Height/Styling
How to Input Multibyte Characters in Rails Console (Or Irb)
Use Rspec's "Expect" etc. Outside a Describe ... It Block
Best Practices in Ruby for Loop
Ruby Tcpsocket Write Doesn't Work, But Puts Does
Thread Safe Enumerator in Ruby
Rails 4 Devise 3.1.1 Actioncontroller::Unknownformat in Devise::Registrationscontroller#New
Rails: How to to Download a File from a Http and Save It into Database
Irb: How to Start an Interactive Ruby Session with Pre-Loaded Classes