How to customize error messages for validates numericality sub-options? - ruby-on-rails-3

How can I customize the error messages for sub options when validating numericality on a field in an ActiveRecord model?
Example:
validates :month, :numericality => {
:greater_than_or_equal_to => 1,
:less_than_or_equal_to => 12
}
In this case if the 'month' attribute is more than 12, I want to provide custom error message instead of the default "must be less than or equal to 12". How to achieve this?

If you don't want to use a custom validator, you could use the en.yml file instead. Assuming "post" was your model name, this provides examples for age-specific messages, post-specific messages, and generic (all models) messages.
en:
activerecord:
errors:
models:
post:
attributes:
age:
less_than_or_equal_to: "Age-specific error" # Applies only to post.age
less_than_or_equal_to: "Post-specific error" # Applies to all other fields for a post
messages:
less_than_or_equal_to: "Generic error" # Applies to all other models

If you want to customize the error messaging depending on the model you can use this syntax:
validates_numericality_of :month,
greater_than_or_equal_to: 1,
less_than_or_equal_to: 12,
message: "My custom error message"
You can also use this syntax to customize error messages based on the specific conditions:
validates_numericality_of :month,
greater_than_or_equal_to: 1,
message: "Too small"
validates_numericality_of :month,
less_than_or_equal_to: 12,
message: "Too big

Related

How to catch 422 Unprocessable entry in laravel 5.5.16

How to catch 422 Unprocessable entry in laravel 5.5.16 ?
I am getting below error message while I am sending http://127.0.0.1:8000/api/topics API request.
I would like to customize this error.In this regard I would like to know Which class and function producing this error and their location.
A 422 Error is thrown when Laravel validates your Request data and the data is wrong, invalid or not processable.
If you are validating your data in an extra Request class, you can add a message method to override the error messages (further info here):
/**
* Get the error messages for the defined validation rules.
*
* #return array
*/
public function messages()
{
return [
'body.required' => 'A message is required',
];
}
If you are validating the data inside your Controller through $request->validate(...), you need to create an own Validator class inline with a messages argument (further info here):
$messages = [
'required' => 'The :attribute field is required.',
];
$validator = Validator::make($input, $rules, $messages);

Mandrill API E-mail queue with sinatra

Trying to get form to send e-mail to Mandrill api. My email keeps getting queued and will not send.
post '/my-handling-form-page' do
m = Mandrill::API.new
message = {
:subject => "Hello from the Mandrill API",
:from_name => "#{params[:name]} #{params[:email]}",
:text => "Hi message how are you?",
:to => [
{
:email => "anonymous#gmail.com",
:name => "Recipient1"
}
],
:html => "<html>#{params[:msg]}</html>",
:from_email => "anonymous#gmail.com"
}
sending = m.messages.send message
puts sending
erb :index
end
Error says:
{"email"=>"anonymous#gmail.com", "status"=>"queued", "_id"=>"216c30f42ee849e2a70528e3d4f9774f", "reject_reason"=>nil}
Help would be appreciated.
From the Mandrill docs:
Why does a delivered message say "queued"?
Mandrill automatically tracks and records the SMTP response we receive
from recipient mail servers for each email you send. Some successfully
delivered emails will include a "queued" notation in the SMTP response
such as 250 OK; queued as 12345. The email has still been delivered to
the recipient as expected, but may require additional processing
before it lands in the recipient's mailbox. For example, most times
Mandrill can send email much faster than recipient servers are able to
accept or process it. In many cases, things like the time of day and
overall email traffic to that ISP or recipient server can affect how
quickly they're able to receive and process your email.
Your code seems fine. Looks there could be an issue with the recipient's server.
A Response Mail From Mandrill :
Thanks for reaching out. In this case, it appears that the API call being passed to Mandrill contains several invalid parameters - however, since you're also passing us an attachment array in that API call, you won't see the response indicating that it's an invalid API call.
Whenever Mandrill receives an attachment, we will always return a response of "Queued," as our systems will set that message aside to scan the attachment for viruses/malware before we process it in any other way. This means that, if something else is wrong with the API call, you won't be alerted, and it will "silently" fail.
It looks as though you've included several parameters from our default API docs, but those are intended to show users how those parameters would be included.
**"subaccount"**: "customer-123",
and
**"ip_pool"**: "Main Pool",
Will both cause this API call to fail, as you're specifying options that don't exist within your account. I would recommend that you go through your API code and remove anything that you aren't using. For reference, the minimum API call required to send an email would look like:
{
"message": {
"html": "<html content>",
"subject": "<subject>",
"from_email": "<sender email address>",
"from_name": "<sender name>",
"to": [
{
"email": "<recipient email address>",
"name": "<recipient name>",
"type": "to"
}
],
"headers": {
"Reply-To": "<reply-to address>"
}
},
"async": false,
"ip_pool": null,
"send_at": null,
"key": "<valid API key>"
}
So after this valuable response this what that work in Django for me :)
def send_mail_msg():
import mandrill
try:
mandrill_client = mandrill.Mandrill('xxxxxxxxxxxxxxx')
message = {
# 'attachments': [{'content': 'ZXhhbXBsZSBmaWxl',
# 'name': 'myfile.txt',
# 'type': 'text/plain'}],
'auto_html': None,
'auto_text': None,
# 'bcc_address': 'message.bcc_address#example.com',
'from_email': 'xxxxx#xxxx.com',
'from_name': 'Example Name',
'global_merge_vars': [{'content': 'merge1 content', 'name': 'merge1'}],
'google_analytics_campaign': 'gaurav#nexthoughts.com',
'google_analytics_domains': ['example.com'],
# 'headers': {'Reply-To': 'message.reply#example.com'},
'html': '<p>Example HTML content</p>',
'images': [{'content': 'ZXhhbXBsZSBmaWxl',
'name': 'IMAGECID',
'type': 'image/png'}],
'important': False,
'inline_css': None,
'merge': True,
'merge_language': 'mailchimp',
# 'merge_vars': [{'rcpt': 'recipient.email#example.com',
# 'vars': [{'content': 'merge2 content', 'name': 'merge2'}]}],
'metadata': {'website': 'www.example.com'},
'preserve_recipients': None,
'recipient_metadata': [{'rcpt': 'recipient.email#example.com',
'values': {'user_id': 123456}}],
'return_path_domain': None,
'signing_domain': None,
# 'subaccount': 'customer-123',
'subject': 'example subject',
'tags': ['password-resets'],
'text': 'Example text content',
'to': [{'email': 'xxxxx#xxxx.com',
'name': 'Recipient Name',
'type': 'to'}],
'track_clicks': None,
'track_opens': None,
'tracking_domain': None,
'url_strip_qs': None,
'view_content_link': None}
result = mandrill_client.messages.send(message=message, async=False, ip_pool='Main Pool')
# send_at=str(datetime.datetime.now().time()))
'''
[{'_id': 'abc123abc123abc123abc123abc123',
'email': 'recipient.email#example.com',
'reject_reason': 'hard-bounce',
'status': 'sent'}]
'''
return result
except mandrill.Error as e: # Mandrill errors are thrown as exceptions
print 'A mandrill error occurred: %s - %s' % (e.__class__, e)
# A mandrill error occurred: <class 'mandrill.UnknownSubaccountError'> - No subaccount exists with the id 'customer-123'
raise`
According to Mandrill api:
subaccount
the unique id of a subaccount for this message - must already exist or will fail with an error.
(At least for me the test start working after removing that field).
Mandrill definitely should improve their response errors.

respond_with is asking for location on error

I have a pretty standard authenticate method
private
def authenticate_user
#current_user = User.find_by_authentication_token(params[:token])
unless #current_user
error = { :error => "Invalid token." }
respond_with(error, :status => 401 )
end
end
I am calling the API to ensure the authenticate fails.
I get an error stating
ArgumentError (Nil location provided. Can't build URI.):
app/controllers/api/v1/base_controller.rb:13:in `authenticate_user'
What am I doing wrong?
By the specific flavor of your error, I am guessing that "authenticate_user" is called as part of a "create" action.
If that is the case, I believe the answer I provided here will help you as well.
Assuming, however, that this is part of creating an authenticated session, meaning there is no actual location for the newly created "resource", I would supply nil for the response location, as in:
...
respond_with(error, :status => 401, :location => nil)
...
That will make more sense once you have a look at the linked answer. If it still doesn't make sense, I'll be happy to clarify.
I changed respond_with to render and it worked:
render json: { success: false, message: "an error" }, status: 500

extjs4 rails 3 model validation for uniqueness

i m working with extjs 4 & rails 3.
I want to have validation for uniqueness of field that is on extjs form.
I want to have validation on Rails model for uniqueness, so i have done follwing on my rails model :
validates_uniqueness_of :search_key, :message => "Duplicate value found"
I am inserting new values of form into store as follows :
store.add(values);
If validation fails, the record does not get inserted into database.
Now I want to pop an alert box indicating that the entry is duplicate when validation fails, so that user can edit field.
How can i make this communication betwn rails controller & extjs form for validation?
Also would rails callback will be useful in it?
Here is how to pass messages returned from server to extjs app, I assume you can modify this to suit your need, or let me know if I need to clarify anything:
Extjs
in model, add:
proxy: {
type: 'rest',
url: '/manifest-items',
reader: {
type: 'json', // We expect the server to give us a JSON string as a response
root: 'rows',
totalProperty: 'total',
messageProperty: 'message',
}
},
Rails Controller
Then, in both cases of error or success, returned response should be:
render :json => {:success => false, :message => "some error", :rows => [something], :total => x}.to_json
Back to Extjs
In extjs, the message can be accessed as follows:
important: note the difference between getting error message in failure and success cases.
manifestItem.save({
success: function(records, operation) {
Ext.Msg.alert(operation.resultSet.message);
},
failure: function(records, operation) {
Ext.Msg.alert(operation.error);
}
});

Rails 3 assertions failure message: "Expected block to return true value" not helpful; what gives?

This occurs frequently in my controller and route tests. Example, given the route
match "/about", :to => "about#profile"
And the test
test "/about goes to about/profile" do
assert_generates "/about/", { :controller => "about", :action => "profile" }
end
The only failure message is "Expected block to return true value". This happens also with tests like:
test "bills should redirect to /bills" do
get :bills
assert_redirected_to user_bills_path(#user)
end
If my controller doesn't' redirect to user_bills_path(#user), I get the same error: "Expected block to return true value"
This is very annoying for test-driving, as I cannot easily check that my assertion is failing before writing production code or failing because I've written the incorrect test.
It seems to be coming from Rails testing stuff. Any way to avoid this or get better messages?