Alessia
Alessia

Reputation: 13

Rails: When I click on edit in my partial it always edits the same id

I'm a newbie and as you will probably see from my files, I don't fully know what I'm doing :( . At the moment I have a user and a project model. A project belongs to a user, a user has many projects. I have created a user profile page that shows all projects belonging to that user. I would like to give the user the chance to edit or delete the project directly from his profile. At the moment Delete seems to work and Edit only works if the user first clicks on "show" and then edits the project. But when the user clicks on edit from his profile, the project to be edited is not the one clicked.

This is my profile view (views/users/show):

    <% provide(:title, @user.name) %>
    <div class="row">
      <aside class="col-md-4">
        <section class="user_info">
          <h1>
            <%= @user.name %>
          </h1>
        </section>
      </aside>
      <div class="col-md-8">
        <% if @user.projects.any? %>
          <h3>Projects (<%= @user.projects.count %>)</h3>
          <ol class="projects">
            <%= render @projects %>
          </ol>
          <%= will_paginate @projects %>
        <% end %>
      </div>
    </div>

This is the _project partial with the edit link:

    <li id="project-<%= project.id %>">

  <span class="title">
      Title: <%= project.title %></span><br>
  <span class="status">
  <span class="user">
      Submitted By: <%= link_to project.user.name, project.user %></span><br>
  <span class="description">
      Description: <%= project.description %></span><br>
  <span class="status">
      Status:<%= project.status %></span><br>
  <span class="p_type">
      Type: <%= project.p_type %></span><br>
  <span class="timestamp">
    Updated: <%= time_ago_in_words(project.updated_at) %> ago.
    <% if current_user?(project.user) %>
      <%= link_to "delete", project, method: :delete,
                                       data: { confirm: "You sure?" } %>
      <%= link_to "edit", edit_project_path %>  
      <%= link_to "New Project!", new_project_path %>
    <% end %>
<!--  <%= link_to "show", project, method: :get %> -->  
  </span>
</li>

This is my projects controller:

class ProjectsController < ApplicationController
  before_action :logged_in_user, only: [:create, :edit, :destroy]
  before_action :correct_user,   only: [:edit, :destroy]

  def index
    @projects = Project.paginate(page: params[:page])
  end

  def show
    @project = Project.find(params[:id])
  end


  def new
    @project = Project.new
  end

  def create
      @project = current_user.projects.build(project_params)
    if @project.save
      flash[:success] = "Project created!"
      redirect_to root_url
    else
      @feed_items = []
      render 'new'
    end
  end   

  def edit
    @project = Project.find params[:id]
  end

  def update
    @project = Project.find params[:id]
    @user = User.find(params[:id])
    if @project.update(project_params)
      flash[:success] = "Project updated"
      redirect_to user_path(@user)
    else
      render 'edit'
    end
  end

  def destroy
    @project.destroy
    flash[:success] = "Project deleted"
    redirect_to request.referrer || root_url
  end


    private

    def project_params
      params.require(:project).permit(:description, :title, :status, :p_type)
    end

    def correct_user
      @project = current_user.projects.find_by(id: params[:id])
      redirect_to root_url if @project.nil?
    end
end

My project model:

    class Project < ApplicationRecord
      belongs_to :user
      default_scope -> { order(updated_at: :desc) }
      validates :user_id, presence: true
      validates :description, presence: true, length: { maximum: 250 }
      validates :title, presence: true, length: { maximum: 60 }
      validates :p_type, presence: true
      validates :status, presence: true
    end

My routes file:

Rails.application.routes.draw do

  root   'static_pages#home'

  get    '/help',    to: 'static_pages#help'
  get    '/about',   to: 'static_pages#about'
  get    '/contact', to: 'static_pages#contact'
  get    '/signup',  to: 'users#new'
  get    '/login',   to: 'sessions#new'
  post   '/login',   to: 'sessions#create'
  delete '/logout',  to: 'sessions#destroy'

  resources :users
  resources :account_activations, only: [:edit]
  resources :password_resets,     only: [:new, :create, :edit, :update]
  resources :projects

end

Lastly if it helps, when I do the edit operation, this is the trace:

Started GET "/projects/1/edit" for 86.44.57.230 at 2016-10-29 12:16:49 +0000
Cannot render console from 86.44.57.230! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by ProjectsController#edit as HTML
  Parameters: {"id"=>"1"}
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  Project Load (0.2ms)  SELECT  "projects".* FROM "projects" WHERE "projects"."user_id" = ? AND "projects"."id" = ? ORDER BY "projects"."updated_at" DESC LIMIT ?  [["user_id", 1], ["id", 1], ["LIMIT", 1]]
  Project Load (0.2ms)  SELECT  "projects".* FROM "projects" WHERE "projects"."id" = ? ORDER BY "projects"."updated_at" DESC LIMIT ?  [["id", 1], ["LIMIT", 1]]
  Rendering projects/edit.html.erb within layouts/application
  Rendered shared/_error_messages.html.erb (0.6ms)
  Rendered projects/edit.html.erb within layouts/application (24.9ms)
  Rendered layouts/_shim.html.erb (0.4ms)
  Rendered layouts/_header.html.erb (1.0ms)
  Rendered layouts/_footer.html.erb (0.4ms)
Completed 200 OK in 179ms (Views: 172.4ms | ActiveRecord: 0.7ms)

Also adding the edit form

<% provide(:title, "Edit Project") %>
<h1>Update your Project</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_for(@project) do |f| %>
      <%= render 'shared/error_messages', object: f.object %>

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

      <%= f.label :p_type %>
      <%= f.select :p_type, ([['QuickWin', 'QuickWin'],
        ['Project', 'Project']]) %>

      <%= f.label :status %>
      <%= f.select :status, ([['Not Yet Started', 'Not Yet Started'], 
          ['In Progress', 'In Progress'], ['In Testing', 'In Testing'], 
          ['On Hold', 'On Hold'], ['Launched', 'Launched']]) %>

      <div class="field">
        <%= f.text_area :description, placeholder: "Briefly summarise the purpose of this project..." %>
      </div>

      <%= f.submit "Save changes", class: "btn btn-primary" %>
    <% end %>

  </div>
</div>

Thank you in advance for your help!

Upvotes: 0

Views: 54

Answers (1)

rfellons
rfellons

Reputation: 666

On the below row is missing what is the record you wanna change:

<%= link_to "edit", edit_project_path %> 

Add to 'edit_project_path' the project reference:

<%= link_to 'edit', edit_project_path(project) %>

I hope this help you.

...

About the error "Couldn't find User with 'id'=424" on call @user = User.find(params[:id]) on your comment ...

When you click on submit you send a PUT action on controller projects_controller.rb on method update with params with a Project object.

In your projects_controller.rb, your method 'update' receive a Project object.

Here params must appear as

params = { ... project:{:title => '...' , :ptype => ..}, 'id' => XXX }

this 'id' is the project.id !!

projects_controller.rb file

def update
  @project = Project.find params[:id]
  @user = User.find(params[:id])  <= you try to find a User with project.id

I think you wanna find user in join with this 'project'.

@user = @project.user

Upvotes: 1

Related Questions