Search code examples
ruby-on-railsruby-on-rails-4nomethoderror

Why can't I display an edit form?


I've created an app where a user has_one profile and a profile belongs_to a user. It's set up so the profile is automatically created when a user is created (in the user controller)

I am not trying to set it up so a user can visit an edit page (profile controller -> edit action) and edit their profile information through a rendered form (using a _form partial)

I cannot work out why I can't get the edit form to display, as far as I can tell the method is defined correctly?. Anyone got any ideas why? Greatly appreciate any help!

Browser:

NoMethodError in ProfilesController#edit
undefined method `user' for nil:NilClass    

  def edit
    @profile = @profile.user
  end

  def destroy

Profile Controller:

class ProfilesController < ApplicationController
  before_action :logged_in_user,  only: [:edit, :destroy]

  def edit
    @profile = @profile.user
  end

  def destroy
  end
end

User Controller

class UsersController < ApplicationController
  before_action :logged_in_user,  only: [:edit, :update]
  before_action :correct_user,    only: [:edit, :update]

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      @user.profile = Profile.new
      @user.send_activation_email
      flash[:info] = "Please check your email to activate your account."
      redirect_to root_url
    else
      render 'new'
    end
  end

...

views/profiles/edit.html.erb

<% provide(:title, 'Edit Profile') %>
<h1>Editing profile</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for(@profile) do |f| %>
      <%= render 'form', f: f %>
      <%= f.submit "Edit Information", class: "btn btn-primary" %>
    <% end %>
  </div>
</div>

views/profiles/_form.html.erb

<%= render 'shared/error_messages' %>

<%= f.label :first_name %>
<%= f.text_field :first_name, class: 'form-control' %>

...

Solution

  • Without knowing what your authentication system looks like, though you mentioned you looked at devise and built your own, so I think you need to do something like this in your edit action

      def edit
        @profile = current_user.profile
      end