I'm new to rails and am working on a simple reddit-type app for practice. I'm trying to let users update the link they have posted. This is the links_controller:-
class LinksController < ApplicationController
before_action :logged_in_user, only: [:new, :create, :edit, :update]
#before_action :correct_user, only: [:edit, :update]
def new
@link = Link.new
end
def create
@user = current_user
@link = @user.links.build(params)
if @link.save
flash[:success]= "Link submittd successfully"
redirect_to root_path
else
flash[:danger]= "Link submission failed"
render 'new'
end
end
def edit
@user = current_user
@link = @user.links.find_by(id: params[:id])
end
def update
@user = current_user
@link = @user.links.find_by(id: params[:id])
if @link.update_attributes(params)
flash[:success] = "Link successfully edited"
redirect_to current_user
else
flash[:danger] = "Link edit failed"
render 'edit'
end
end
private
# def link_params
# params.permit(:title, :url)
# end
def logged_in_user
redirect_to login_path unless logged_in
end
def correct_user
@link = current_user.links.find_by(id: params[:id])
redirect_to root_path if @link.nil?
end
end
Currently I'm facing this error:-
Log:-
Started GET "/edit_link" for ::1 at 2017-05-23 13:20:56 +0530
Processing by LinksController#edit as HTML
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
Link Load (0.2ms) SELECT "links".* FROM "links" WHERE "links"."user_id" = ? AND "links"."id" IS NULL ORDER BY "links"."created_at" DESC LIMIT ? [["user_id", 1], ["LIMIT", 1]]
Rendering links/edit.html.erb within layouts/application
Rendered links/edit.html.erb within layouts/application (4.6ms)
Completed 500 Internal Server Error in 70ms (ActiveRecord: 1.6ms)
ActionView::Template::Error (First argument in form cannot contain nil or be empty):
4: <div class="row">
5: <div class="col-md-6 col-md-offset-3">
6:
7: <%= form_for(@link, url: edit_link_path) do |f| %>
8:
9: <%= f.label :title %>
10: <%= f.text_field :title, class: 'form-control' %>
This is the edit form for the link:-
<% provide(:title, 'Edit Link') %>
<h1>Edit Link</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(@link, url: edit_link_path) do |f| %>
<%= f.label :title %>
<%= f.text_field :title, class: 'form-control' %>
<%= f.label :url %>
<%= f.text_field :url, class: 'form-control' %>
<%= f.submit "Save Changes", class: "btn btn-primary" %>
<% end %>
</div>
</div>
The routes file:-
Rails.application.routes.draw do
root 'static_pages#home'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
get '/signup', to: 'users#new'
post '/signup', to: 'users#create'
get '/submit_link', to: 'links#new'
post '/submit_link', to: 'links#create'
get '/edit_link', to: 'links#edit'
patch '/edit_link', to: 'links#update'
get '/contact', to: 'static_pages#contact'
resources :users
resources :links
end
As it stands it is really messy. There are many different things that could be wrong and I don't have enough grasp over the various factors to find out the best way to do this.
I'm especially struggling with the params, strong params.
Basically this is what I'm trying to implement:-
- Only logged in user who is the owner of the link can access the edit and update actions for the link. I'm using the before_action filters to ensure this.
- I'm using strong params as defined in the link_params method in private
I'm not 100% sure on the code in the edit and update actions. What I've listed up there is just what I think should be the logical code.
If you could show me how to get this to work and also the best practice to be followed while doing this, it would be great.
Update:- I tried to use link_params earlier but that seemed to generate the error of the required link not being present, so I have muted it for now and am trying to work out how to get it to work through params first.
As it stands it seems that the edit and update actions are not receiving the params[:id] that is required for them to proceed with the action. I don't know how to get the params to be accessible in the actions. I've used the custom route get "edit_link_path" for the links#edit and patch "edit_link_path" for the links#update. Don't know if this is a problem.
Most recent update:-
updated routes.rb (with the link.id appendage to edit and update routes):-
Rails.application.routes.draw do
root 'static_pages#home'
get '/login', to: 'sessions#new'
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
get '/signup', to: 'users#new'
post '/signup', to: 'users#create'
get '/edit_link/link.id', to: 'links#edit'
patch '/edit_link/link.id', to: 'links#update'
get '/submit_link', to: 'links#new'
post '/submit_link', to: 'links#create'
get '/contact', to: 'static_pages#contact'
resources :users
resources :links
end
A list of all available routes:-
$ rails routes
Prefix Verb URI Pattern Controller#Action
root GET / static_pages#home
login GET /login(.:format) sessions#new
POST /login(.:format) sessions#create
logout DELETE /logout(.:format) sessions#destroy
signup GET /signup(.:format) users#new
POST /signup(.:format) users#create
GET /edit_link/link.id(.:format) links#edit
PATCH /edit_link/link.id(.:format) links#update
submit_link GET /submit_link(.:format) links#new
POST /submit_link(.:format) links#create
contact GET /contact(.:format) static_pages#contact
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
links GET /links(.:format) links#index
POST /links(.:format) links#create
new_link GET /links/new(.:format) links#new
edit_link GET /links/:id/edit(.:format) links#edit
link GET /links/:id(.:format) links#show
PATCH /links/:id(.:format) links#update
PUT /links/:id(.:format) links#update
DELETE /links/:id(.:format) links#destroy links#update
PUT /links/:id(.:format) links#update
DELETE /links/:id(.:format) links#destroy
Currently the error is No route matches [PATCH] "/links/2/edit"
As you can see above in the list of available routes, there is a "edit_link GET /links/:id/edit(.:format) links#edit" but there is no equivalent for the update action even though the routes.rb file has the listing for that. Don't understand why.