0
votes

I am the stage when I want to implement user profiles in my web app. I did some research and tried to create something based on what I read. I encountered problem with ProfilesControllers - I have not encountered this in any post that have read. So here we go: I followed these topics: Profile model for Devise users? and Creating Profile for Devise users and this Devise User Profile link_to.

The error I have is uninitialized constant ProfilesController.

header.html.erb (layout)

  <header id="home">
    <div class="main-nav">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
            <%= link_to(image_tag('logo.png', :class => 'img-responsive'), root_path, :class => "navbar-brand") %> 
        </div>
        <div class="collapse navbar-collapse">
          <ul class="nav navbar-nav navbar-right">                 
            <li><%= link_to "Home", root_path, :class => "active" %></li>
            <li><%= link_to "View Profile", profile_path(current_user) %></li>
          </ul>
        </div>
      </div>
    </div><!--/#main-nav-->
  </header><!--/#home-->

routes.rb

Ims::Application.routes.draw do

  root 'pages#home'

  devise_for :users
  resources :articles



  get 'articles/index'
    authenticated :user do
    root :to => 'articles#index', :as => :authenticated_root
  end
  get '/:id', to: 'profiles#show', as: :profile
end

User.rb

  has_one :profile

  #Profile
  accepts_nested_attributes_for :profile 

Profile.rb

class Profile
  include Mongoid::Document

  belongs_to :user
    attr_accessible :uname
end

new.html.erb (devise registration)

<%= render 'layouts/header' %>

<div class="wrapper">
  <div class="signup">
  <p class="title">Register</p>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= devise_error_messages! %>

    <i class="fa fa-user"></i>
      <div class="field">
        <%= f.label :username %><br />
        <%= f.text_field :username, autofocus: true %>
      </div>

      <div class="field">
        <%= f.label :email %><br />
        <%= f.email_field :email, autofocus: true %>
      </div>

      <div class="field">
        <%= f.label :password %>
        <% if @minimum_password_length %>
        <em>(<%= @minimum_password_length %> characters minimum)</em>
        <% end %><br />
        <%= f.password_field :password, autocomplete: "off" %>
      </div>

      <div class="field">
        <%= f.label :password_confirmation %><br />
        <%= f.password_field :password_confirmation, autocomplete: "off" %>
      </div>

      <div class="field">
        <%- if controller_name != 'sessions' %>
          Or <%= link_to "Log in", new_session_path(resource_name) %><br />
        <% end -%>
      </div>


<%= f.fields_for :profile do |profile_form| %>
  <h2><%= profile_form.label :uname %></h2>
  <p><%= profile_form.text_field :uname %></p>
<% end %>



      <div class="actions">
        <button>
          <%= f.submit "Register", :class => "login-button" %>
        </button>
      </div>

    <% end %>

  </div>
</div>

<%= render 'layouts/footer' %>

That is all. As you can see I don't have ProfilesController (I have created it but it's empty). I don't really know what to do with it.

And by the way, I am using MongoID. (if it matters)

1

1 Answers

1
votes

Best way is to use a before_create on your User model to build the profile, then you just have to edit it:

#app/models/user.rb
class User < ActiveRecord::Base
   has_one :profile
   before_create :build_profile
   accepts_nested_attributes_for :profile
end

To edit it, use a singular resource:

#config/routes.rb
resource :profile, only: [:show, :update] #-> url.com/profile

#app/controllers/profiles_controller.rb
class ProfilesController < ApplicationController
   def show
   end

   def update
      current_user.update profile_params
   end

   private

   def profile_params
      params.require(:user).permit(profile_attributes: [])
   end
end

#app/views/profile/show.html.erb
<%= form_for current_user do |f| %>
   <%= f.fields_for :profile do |p| %>
      <%= p.text_field ... %>
   <% end %>
   <%= f.submit %>
<% end %>

Personally, I would avoid adding any extras to the Devise registration process; just redirect the user after successful sign-up if you want them to edit the profile.