Question

I have an app where user signs up with an email (Devise) or Omniauth which is working fine. I added a method to create a profile after the user sign up. Also in the views I want to have user info and profile info in the same page. I am not sure if I did the associations incorrectly or in my controllers but I get this error:

This is the error I am getting:

ActiveRecord::RecordNotFound in ProfilesController#edit
Couldn't find Profile with id=25
Extracted source (around line #58): @profile = Profile.find(params[:id])

These are the models I am using:

class User < ActiveRecord::Base
  after_create :create_profile
  has_one :profile, :dependent => :destroy

  private
  def create_profile
    Profile.create(user: self)
  end
end

class Profile < ActiveRecord::Base
  belongs_to :user
end

And this is the Profiles controller:

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

  def index
    @profiles = Profile.all
    @profile = current_user.profile
  end

  def show
    @user = User.find(params[:id])
    @profile = @user.profile
  end

  def new
    @profile = Profile.new
  end

  def edit
    @profile = current_user.profile #there was nothing before
  end

  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 action: 'show', status: :created, location: @profile }
      else
        format.html { render action: 'new' }
        format.json { render json: @profile.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    @profile = current_user.profile #there was nothing before
    respond_to do |format|
      if @profile.update(profile_params)
        format.html { redirect_to @profile, notice: 'Profile was successfully updated.' }
        format.json { render action: 'show', status: :ok, location: @profile }
      else
        format.html { render action: 'edit' }
        format.json { render json: @profile.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @profile.destroy
    respond_to do |format|
  format.html { redirect_to profiles_url }
      format.json { head :no_content }
    end
  end

  private
    def set_profile
      @profile = Profile.find(params[:id])
    end

    def profile_params
      params.require(:profile).permit(:first_name, :last_name, :headline)
    end
end

And the views:

<!-- views/profiles/_form.html.erb -->

<%= simple_form_for(@profile) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :first_name %>
    <%= f.input :last_name %>
    <%= f.input :headline %>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

<!-- views/layouts/navigation.html.erb -->
<% if user_signed_in? %>
  <p class="navbar-text navbar-left">Hello <a href="#" class="navbar-link"><%= @user.name %></a>!</p>
<% end %>

<% if user_signed_in? %>
  <li><%= link_to 'Logout', destroy_user_session_path, :method=>'delete' %></li>
<% else %>
  <li><%= link_to 'Sign in with your Email', new_user_session_path %></li>
  <li><%= link_to "Sign in with Google", user_omniauth_authorize_path(:google_oauth2) %></li>
  <li><%= link_to "Sign in with Facebook", user_omniauth_authorize_path(:facebook) %></li>
<% end %>

<% if user_signed_in? %>
  <li><%= link_to 'Users', users_path %></li>
<% end %>

<% if user_signed_in? %>
  <li class="dropdown">
    <a href="" class="dropdown-toggle" data-toggle="dropdown">Account <b class="caret"></b></a>
      <ul class="dropdown-menu">
        <li><%= link_to 'Edit profile', edit_profile_path(@user) %></li>
        <li><%= link_to 'Edit settings', edit_user_registration_path %></li>
      </ul>
  </li>
<% else %>
  <li><%= link_to 'Sign up', new_user_registration_path %></li>
<% end %>

Please let me know If there is something wrong in my code or how to fix the problem I am having. Also, if there is something else I should put here from my code. Thank you in advance!

Was it helpful?

Solution

You may try this to handle the error when profile of current user is missing in database

def edit
  unless current_user.profile.blank?
    @profile = current_user.profile
  else
    flash[:notice] = "No profile exists for current user"
    redirect_to root_path
  end 
end

You anyway want profile for current user so you should better remove before_filter :set_profile for edit action

OTHER TIPS

It seems like at the first time you do not have the user profile so in the edit action

def edit
    @profile = current_user.profile #there was nothing before
  end

def set_profile
  @profile = Profile.find(params[:id])
end

there is no profile for the current user please check in the data base after creating a fresh user record. If a new profile record is creating or not.

try to change the after create method like this .

def create_profile create_profile.create!() end There may be validation error.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top