Search code examples
rubyruby-on-rails-3ruby-on-rails-3.1ruby-on-rails-3.2

extract objects that did not pass validations and show them in notifications


Intro: In short, this action let's you invite more users by mail, there is a field where you put your emails and on submit they all get emails with invitation by mail.

there is a method in the model that validates the email on project_invitation create so, inserting an invalid email type (like: eee@em, fff.com, [email protected]), pinv will not be saved and logger.error will be raised..

The problem: How do I extract all the emails that did not pass the validation and display them in a notice, something like "Invtations sent, except eee@em, fff.com, [email protected], emails not valid".

Thank you, if any other info is needed, please let me know.

  def invite_users
    emails = params[:project_invitation][:emails]
    role = current_user.has_role?(:admin, @project) ? :admin : :default

    emails.to_s.split(',').each do |email|
      pinv = ProjectInvitation.new(params[:project_invitation], as: role)
      pinv.sender = current_user
      pinv.recipient_email = email
      pinv.recipient = nil
      pinv.project = @project

      if pinv.save
        ProjectMailer.delay.invitation(pinv)
      else
        logger.error("Failed to save project inv: #{pinv.errors.full_messages.join("\n")}")
      end
    end
  end

Solution

  • Capture the emails within your block, above your logger.error:

      invalid_emails = []
    
      if pinv.save
        ProjectMailer.delay.invitation(pinv)
      else
        invalid_emails << email
        logger.error("Failed to save project inv: #{pinv.errors.full_messages.join("\n")}")
      end
    
      if invalid_emails.any?
        flash[:notice] = "Invalid emails: #{invalid_emails.join(', ')}"
      end
    

    The whole code:

      def invite_users
        emails = params[:project_invitation][:emails]
        role = current_user.has_role?(:admin, @project) ? :admin : :default
    
        invalid_emails = []
    
        emails.to_s.split(',').each do |email|
          pinv = ProjectInvitation.new(params[:project_invitation], as: role)
          pinv.sender = current_user
          pinv.recipient_email = email
          pinv.recipient = nil
          pinv.project = @project
    
          if pinv.save
            ProjectMailer.delay.invitation(pinv)
          else
            invalid_emails << email
            logger.error("Failed to save project inv: #{pinv.errors.full_messages.join("\n")}")
          end
        end
    
        if invalid_emails.any?
          flash[:notice] = "Invalid emails: #{invalid_emails.join(', ')}"
        end
      end