Search code examples
ruby-on-railshttp-redirectactioncontroller

Cannot redirect to nil! ActionController::ActionControllerError


I've got an app where: 1. user is on a page viewing their profile information 2. user presses button to email someone from this page 3. after the email is sent, user is sent back to view their profile information again and a notice flashes to tell them if the email worked or not.

I'm having with no. 3. I'm not sure how to set up a redirect (or something else appropriate) that will send a user to view their profile info again

Controller:

class ProfilesController < ApplicationController
  before_action :set_profile, only: [:show, :edit, :update, :destroy, :email]

  # GET /profiles
  # GET /profiles.json
  def index
    @profiles = Profile.all
  end

  # GET /profiles/1
  # GET /profiles/1.json
  def show
  end

  # GET /profiles/new
  def new
    @profile = Profile.new
  end

  # GET /profiles/1/edit
  def edit
    @profile = Profile.find_by user_id: current_user.id
  end

  # POST /profiles
  # POST /profiles.json
  def create
    @profile = Profile.new(profile_params)

    respond_to do |format|
      if @profile.save
        format.html { redirect_to @profile, notice: 'Profile was successfully created.' }
        format.json { render :show, status: :created, location: @profile }
      else
        format.html { render :new }
        format.json { render json: @profile.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /profiles/1
  # PATCH/PUT /profiles/1.json
  def update
    respond_to do |format|
      if @profile.update(profile_params)
        format.html { redirect_to @profile, notice: 'Profile was successfully updated.' }
        format.json { render :show, status: :ok, location: @profile }
      else
        format.html { render :edit }
        format.json { render json: @profile.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /profiles/1
  # DELETE /profiles/1.json
  def destroy
    @profile.destroy
    respond_to do |format|
      format.html { redirect_to profiles_url, notice: 'Profile was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  def email_profile
    destination = params[:to]
    share = Share.profile(@profile, destination)
    if destination =~ /@/ && share.deliver
      redirect_to @profile, notice: 'email sent'
    else 
      redirect_to @profile, notice: 'email failed'
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_profile
      @profile = Profile.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def profile_params
      params.require(:profile).permit(:user_id, :first_name, :last_name, :dob, :email, :mobile, :address, :suburb, :postcode, :city, :state, :country)
    end
end

Share Mailer:

  class Share < ActionMailer::Base
    default_url_options[:host] = "localhost:3000"
  default from: "[email protected]"

  def profile(profile, destination)
   @profile = profile
   mail(to: destination, subject: "sent you stuff")
  end
end

Current error:

ActionController::ActionControllerError in ProfilesController#email_profile
Cannot redirect to nil!

I think it has something to do with the :id parameter not being passed through after the email is sent.. but I'm a newbie so I don't really know what I'm talking about.. appreciate any guidance so I can fix this and also better understand ROR :)


Solution

  • You probably need to find a @profile first. I guess something like Profile.find(params[:profile_id]) is missing.