Dan Tappin
Dan Tappin

Reputation: 3032

Rails routing to update a model without passing an :id

I have a pretty basic 'User' model, control & views for a Rails app. I am trying to add a 'profile' section where the user can update their user info after logging in (and storing their user_id as a session variable).

I have scaffolded a basic 'profile' model, controller and views (_form, index and edit all using simple_form). The model is empty and the views are pretty much a copy of the user views except I have moved the 'show' format to the profile index view. In my controller I pretty much copied the user controller, deleted the new, create, show and destroy actions.

Here is what I have:

class ProfileController < ApplicationController
  def index
    @profile = User.find(session[:user_id])
  end

  def edit
    @profile = User.find(session[:user_id])
  end

  def update
    @profile = User.find(session[:user_id])

    respond_to do |format|
      if @profile.update_attributes(params[:profile])
        redirect_to @profile, notice: 'Profile was successfully updated.'
      else
        render action: "edit"
      end
    end
  end

 end

I tried both of these routes formats:

  match "profile" => "profile#index"  
  match "profile/edit" => "profile#edit"
  match "profile/update" => "profile#update"

and

  controller :profile do
    put 'profile/update' => :update
    get 'profile' => :index
    get 'profile/edit' => :edit
  end

When I load ~/profile/edit/ the form renders properly and my fields populate. I am using simple_form and here is the start of my _form.html.erb file:

<%= simple_form_for @profile, :url => url_for(:action => 'update', :controller => 'profile'), :html => { :id => "edit_profile", :class => 'form-horizontal' }, :method => 'put' do |f| %>

but simple_form still passes for="user_***" to all the field inputs.

I updated @profile.update_attributes(params[:profile]) to @profile.update_attributes(params[:user]) thinking that was the issue. When I click 'Update User' (still references the User model). The form reloads to ~/profile/update but nothing happens.

I am pretty sure I am missing an obvious routing / model issue here but I can't seem to figure this out on my own.

Upvotes: 3

Views: 4253

Answers (1)

prasvin
prasvin

Reputation: 3019

I presume its not a routing / model issue here. Your edit profile page still references user because your @profile is a User and not a Profile.

First, if you want to follow Rails' convention, which I strongly recommend, use plural form for controller's class as class ProfilesController < ApplicationController.

Then, define routes for your profiles resource as resources :profiles, :only => [:index, :edit, :update]

Your profiles#edit as :

def edit
  @profile = User.find(session[:user_id]).profile #(i.e. if user has_one profile)
  # or @profile = Profile.find(params[:id) depending on what params are being passed here
end

Upvotes: 2

Related Questions