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!

Était-ce utile?

La 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

Autres conseils

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top