Search code examples
ruby-on-railsruby-on-rails-3validationflash-message

Display flash message with model validations


I have the following model validations...

  validates :event_id, :uniqueness => {:scope => :email}
  validates_format_of :email, :with => /\A[^@]+@([^@\.]+\.)+[^@\.]+\z/
  validates_presence_of :email, :first_name, :last_name

..and here is my controller...

def register_learner
    @event = Event.find(params[:event_id])
    begin
      EventRegistration.create! first_name: params[:first_name], last_name: params[:last_name], email: params[:email], event_id: params[:event_id]
      rescue ActiveRecord::RecordInvalid => e
    end
end

This codes work, but the problems is it silently catches the errors. I'd like to display a flash message to the user and in the current page. So I tried this...

   def register_learner
    @event = Event.find(params[:event_id])
    begin
      @registation = EventRegistration.create! first_name: params[:first_name], last_name: params[:last_name], email: params[:email], event_id: params[:event_id]
      rescue ActiveRecord::RecordInvalid => e
      if [email protected]?
        flash[:notice] = @registation.errors
      end
    end
   end

...but I get the message undefined method `valid?' for nil:NilClass if the validation fails.


Solution

  • If you use new instead of create! you will end up with an instance that can tell you valid? == false.

    You also won't need the rescue in this case.

    So you could do something like this:

    def register_learner
      @event = Event.find(params[:event_id])
      @registation = EventRegistration.new(
        first_name: params[:first_name], 
        last_name: params[:last_name], 
        email: params[:email], 
        event_id: params[:event_id]
      )
      flash[:notice] = @registation.errors unless @registation.valid?
    end
    

    Also, if you might already have an existing registration, you could use find_or_initialize_by and then check if the resulting object is a new record with @registration.new_record?.