Reputation: 13
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
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