What is the difference when using flash :error, :alert, and :notice? - ruby-on-rails-3

As the title of the question asks, I am interested in knowing if there is any difference when using flash[:error], flash[:alert], and flash[:notice]. If so, when is it appropriate to use each, and why?

flash is a Rails mechanism to persist some information across 2 requests. You set something in flash hash in one request and it's available in the very next request you receive from that same client.
Since flash is just a "hash" you can use it like one. Which means you can provide your preferred key (:alert/:error/:notice) and put whatever message string you wish as the value.
The semantics of what or when to use :alert/:error/:notice are really up to you to manage. Having said that, the general best practice is to use :notice when things are OKAY and is displayed in a greenish hue, and use :error when things are NOT OKAY and is displayed in a reddish hue. It is completely okay if you want to use :alert for another type of message on your web app. I've used it before for informational purposes in a yellowish hue.

:alert and :notice functionally differ from other keys you invent. FlashHash provides convenience accessors for the two: flash.alert , flash.notice. Rails' preference for these two further rears its way into redirect_to which will only accept :alert, :notice, or :flash.
However, a commit in July 2012 to edge Rails allows the privilege of adding other flash types. Here's an example of adding custom flash types in Rails 4:
# app/controllers/application_controller.rb
class ApplicationController; add_flash_types(:error, :annoyance); end
# app/controllers/monopoly_controller.rb
class MonopolyController < ApplicationController
def chance
...
redirect_to haha_path, annoyance: "Go directly to jail. Do not pass Go. Do not collect $200."
end
end
# app/views/haha/index.html.erb
<%= annoyance %>

this is just a classification. it generates the div #error.error or div#notice.notice you connect the logic you want above
litte sample :
.alert, .error, .notice, .success { padding:.8em 0; margin:0 0 2px 0; border:2px solid #ddd; font-size:1.6em; text-align:center;}
.error { background:#FBE3E4;color:#8a1f11;border-color:#FBC2C4; }
.notice { background:#FFF6BF;color:#514721;border-color:#FFD324; }
.success { background:#DDFCD5;color:#000;border-color:#44A815; }
.alert { background:#FBE3E4;color:#8a1f11;border-color:#FBC2C4; }
.error a {color:#8a1f11;}
.notice a {color:#514721;}
.success a {color:#264409;}
.alert a {color:#8a1f11;}

They are just different classifications. I mainly use :error and :notice. Notice I use for informational messages ("your password has been changed", "changes saved", etc). I reserve :error for critical things/problems ("Your passwords do not match", "Login failed", etc)

I also use a :message class too pass along the StandardError message trapped in my exception handlers. Using 2 or 3 classes allows you to display up to that many messages in response to a single event or result, each conveying a different aspect of the outcome, e.g. informational, an error based on what the application knows and an error based on what the system knows.

Related

Custom strategy for warden not getting called

I am trying to use a different warden strategy to authenticate my action cable end points.
But the strategy is not getting called. I tried to place warden.authenticate!(:action_cable_auth) in a controller to test but none of the debug statements are getting printed on console.
Below are the relevant part of the code.
config/initializers/warden.rb
Warden::Strategies.add(:action_cable_auth) do
def valid?
#check if its a websocket request & for action cable?
#Rails.logger.error request.inspect
p 'checking if strategy is valid?'
true
end
def authenticate!
p 'unauthenticate the user'
fail!('user not active')
end
end
in my controller
warden.authenticate!(:action_cable_auth)
Assuming that you are setting your initializer in the proper place, please recall that if your session is already instantiated somewhere else (for example if you authenticate the user at the point your action is being called, then your strategy will never be called.
This is basically how warden works: if some valid? strategy returns a success! then no other will be called as soon as any authenticate! method in the list of strategies is successful.
Please also be sure that if you want your strategy up the list of strategies to check you may need to also shift it up on the list, such as:
manager.default_strategies(scope: :user).unshift(:action_cable_auth)
Where the manager is your Warden::Manager instance. The scope may also be optional (this is an example where the user scope is used alongside Devise), but you may check your instance .default_strategies to figure out where it is and where you want it.

Rails 3 ActionMailer class loaded but methods not available in controller

Many simmilar Q/A on this topic here and there, but I was unable to find exact solution for my problem. Using Rails 3.0.9 now, and trying to upgrade existing older application(not Rails).
The goal is to send simple email to new clients created by admins.
Have been following this oficial guide (and many others), but with no success.
The issue is, that method(s) defined in this controller, from class 'UserMailer', aren`t recognised from another controller, while class 'UserMailer' itself recognised is(how do I know this, will be explained below):
/app/mailers/user_mailer.rb
class UserMailer < ActionMailer::Base
default :from => "info#xxxxx.sk"
def kokotina # << this is just a dummy method for testing
caf = "ssss"
end
def regMailUsr(nazov, priezvisko, email, pass)
#nazov = nazov
#priezvisko = priezvisko
#email = email
#pass = pass
#url = "http://loyalty2.xxxx.sk"
mail(to: email, subject: 'Vaša registrácia bola dokončená.')
end
end
I have also created View for this mail controller but that is not important right now.
The fragments from clients controller are here:
/app/controllers/clients_controller.rb
# encoding: UTF-8
class ClientsController < ApplicationController
load_and_authorize_resource
.......
def new
#noveHeslo = genHeslo(10) # << I defined this in application_controller.rb and it works
UserMailer.kokotina # << just a dummy method from UserMailer
#client = Client.new(params[:client])
.......
end
.......
def create
.......
if #client.save
#send email to new client:
UserMailer.regMailUsr(params[:client][:fname], params[:client][:lname], params[:client][:email], params[:client][:password]).deliver
.....
end ......
Now how do I know that my class is loaded? If in client controller, I change 'UserMailer' to 'xUserMailer', I will get 'no class or method in ...' error, but without 'x', I get only:
'undefined method `kokotina' for UserMailer:Class'
I also tried to define my methods in UserMailer:Class like this:
def self.kokotina # << this is just a dummy method for testing
caf = "ssss"
end
#or even like this
def self <<
def kokotina # << this is just a dummy method for testing
caf = "ssss"
end
end
#and then tried to invoke this method(s) like this:
UserMailer.new.kokotina
#or simply
kokotina
Strange is, that when I put contents of file '/app/mailers/user_mailer.rb' at the end of 'application_helper.rb' file, just after the end of 'module ApplicationHelper', I get no errors but of course, it won`t work.
Please keep in mind that I have no problem coding in another languages, but this mystic/kryptic rules of Ruby on Rails are still a complete mistery to me and unfortunatelly, I don`t have time or even motivation to read time extensive quides or even books for RoR beginners. I have been coding much more difficult applications and implementations, but this heavily discriminating system is driving me nuts.
Thank you all!
Problem solved!
The trick was, that in '/app/mailers/user_mailer.rb', I had multibyte characters. In mail subject.
So I added:
# encoding: UTF-8
at the very first line of '/app/mailers/user_mailer.rb'
I found this by total accident: later my rails app could not start, and server was simply throwing HTTP 500 error. So no trace, error defining etc.
I found out that multibyte string in:
mail(to: email, subject: 'Vaša registrácia bola dokončená.')
Was responsible for crash. When I removed that string, I noticed one important side effect: my methods became magicaly available for another controller!!!!
So if someone could give me at least one reason to lowe Rails...

Rails 3: How to report error message from the controller's "create" action?

In my "create" action on a form, I successfully save (1) MyObject to my local database and (2) OtherObject to a third-party database via its Ruby API. When something goes wrong with the save to the third party, I get an error in the form of a Ruby exception.
My question is: How do I stop the form submit and report the exception message to the client?
If this is not possible, what would be the best alternative?
Depending on whether you want to rollback your local database call, you might want to consider using Transactions. Something along these lines:
def create
ActiveRecord::Base.transaction do
#myobject = MyObject.create!(params[:myobject])
begin
# call third-party
rescue Exception => e
flash[:exception] = e.message
raise ActiveRecord::Rollback # Raise this to cause a rollback on MyObject
end
end
# redirect_to or render... might have to pick depending on if you got an exception
end
This will store the exception message into the flash which you can use to display to the user. Note Do not store the entire Exception object into the flash, you will definitely see overflow errors if your exception objects are too big.
If you're not too concerned about rolling back the MyObject creation, then you can just use a simple begin...rescue similar to what I showed in my example. You may need to determine whether you want to do a redirect_to or render depending on whether an exception occurred, but you can always conditionally determine that based on whether flash[:exception].nil? is true or not.

Getting started with BDD / TDD (Rails / Rspec)

I'm just starting to learn the practice of BDD / TDD (world rejoices, I know). One of the things that I struggle with at this point is which tests are actually worth writing. Let's take these set of tests which I started for a model called Sport:
Factory.define :sport do |f|
f.name 'baseball'
end
require 'spec_helper'
describe Sport do
before(:each) do
#sport_unsaved = Factory.build(:sport) # returns an unsaved object
#sport_saved = Factory.create(:sport) # returns a saved object
end
# Schema testing.
it { should have_db_column(:name).of_type(:string) }
it { should have_db_column(:created_at).of_type(:datetime) }
it { should have_db_column(:updated_at).of_type(:datetime) }
# Index testing.
# Associations testing.
it { should have_many(:leagues) }
# Validations testing.
it 'should only accept unique names' do
#sport_unsaved.should validate_uniqueness_of(:name)
end
it { should validate_presence_of(:name) }
it 'should allow valid values for name' do
Sport::NAMES.each do |v|
should allow_value(v).for(:name)
end
end
it 'should not allow invalid values for name' do
%w(swimming Hockey).each do |v|
should_not allow_value(v).for(:name)
end
end
# Methods testing.
end
Few specific questions that I have:
Is it worth testing that the association sport.leagues returns a non-blank value?
How about a test that ensure the model is invalid if a name is not specified?
How about a test to make sure that a valid record is created and doesn't have any validation errors?
I could go on. Ideally, there would be some hard and fast rules I could follow to guide my testing effort. But I am guessing this comes with experience and good ole' pragmatism. I've thought about reading through the source code of several gems such as the rails core to gain a better understanding of what's worth testing and what isn't.
Any advice you experienced testers out there could offer?
Not if you're only re-testing Rails behavior.
Yes--it's part of model validation and a requirement, why not make sure the requirement is met?
Testing your assumptions regarding the save process is a good idea, and if there are any lifecycle listeners/observers they may not be fired until the save.
The Rails core tests won't help you decide what's a good idea to test in an application.
What should you test ? Anything you would not want to be broken
When to stop writing tests ? When fear transforms into boredom
So if 1,2,3 are defects if the specified behavior is not exhibited, then you should have tests on all 3.
From the code snippets, personally I'd refrain from checking DB implementation (which columns exist and their details). Reason: I'd want to be able to change that over time without having to break a bunch of tests and fix all of them. Tests should only break if the behavior is broken. If the way (implementation) in which you satisfy them changes, the tests should not break/need modifications.
Focus on the What over the How.
HTH

Ruby on Rails - Suppress an error message

I am using Rails 3 and AJAX and have a parent object which is being created through and AJAX request. This parent is sent with children and saves them all. However, if a child has an error, Rails will stop the request. Is there any way to tell Rails to ignore this? I understand the proper thing to do is find the problem within the Javascript sending the request and fix it. However, for the sake of learning, is there a way to tell Rails that some errors might be ignorable?
To save without validating use:
#parent.save(:validate => false)
Also, don't forget you can create conditional validation rules if needs be. For example, add a virtual attribute (an instance variable that is not persisted to the DB) accessible via bare_bones?. Then modify a validator like so:
validates_presence_of :nickname, :unless => "bare_bones?"
Then, in your controller you would do something like this:
#parent = Parent.new params[:parent]
#parent.bare_bones = true
#parent.save()
Hope this helps.
You are looking for exception handling.
begin
#code that may contain errors
rescue
#what to do if an error is encountered
end