cannot invoke a HTTP delete method not deleting RoR - ruby-on-rails-3

I am following a tutorial and I am trying to invoke a delete method like this:
in users/index.html.erb I got:
<!-- View for index action in user's controleer -->
<h1>All users - Administration Page</h1>
<%= will_paginate %>
<ul class="users">
<% #users.each do |user| %>
<li>
<%= link_to user.name, user %>
<!-- if the current user is admin -->
<% if current_user.admin? && !current_user?(user) %>
| <%= link_to "delete", user, method: :delete, confirm: "You sure?" %>
<% end %>
</li>
<% end %>
</ul>
<%= will_paginate %>
in my users controller I got this:
#destroying users!
def destroy
User.find(params[:id]).destroy
flash[:success] = "User destroyed."
redirect_to users_path
end
instead of getting a confirm box, I am being redirected into the user's profile?!
It seems that rails server cannot read the delete method I am sending to it!
Edit:
rake routes:
rake routes
intergration_test_authentication_pages GET /intergration_test/authentication_pages(.:format) intergration_test#authentication_pages
root / static_pages#home
user_profile /user_profile(.:format) users#show_user
all_videos /all_videos(.:format) static_pages#allvideos
show_interface /show_interface(.:format) static_pages#interface
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
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
sessions POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
session DELETE /sessions/:id(.:format) sessions#destroy
signup /signup(.:format) users#new
signin /signin(.:format) sessions#new
signout /signout(.:format) sessions#destroy

More than likely you are not including the necessary jQuery UJS Javascript on your page. This is what allows the :method parameter to work properly.

I saw a few problems in the syntax on your link_to. Try updating this part:
:method => :delete, :confirm => "You sure?"

Related

Which is the best practice in trying to get the edit and update actions to work with before_action filters and strong params

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.
Ok, finally figured it out and fixed everything. The problem was with the routing. I had to route the link id in the routes for edit and update and it had to be patch '/link.:id'. Everything else including strong params and correct_user works after that. Great!

Rails App session error, can't signin

I'm creating my first solo project with rails and users can't seem to sign in. I call my sign in method immediately after the user is created, but if they sign out the app will not let them sign back in. Here is what I am getting when submitting the sign in form
Here is the error message
undefined method `[]' for nil:NilClass
it says it is in line 6 of the sessions controller but I think something else is wrong
Sessions Controller
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
sign_in user
redirect_to user
else
flash.now[:error] = 'Invalid email/password combination'
render 'new'
end
end
def destroy
sign_out
redirect_to root_path
end
end
Login form
<h1>Sign in</h1>
<br />
<%= form_tag sessions_path do %>
<%= label_tag :email %><br />
<%= text_field_tag :email %><br />
<%= label_tag :password %><br />
<%= text_field_tag :password %><br />
<%= submit_tag "Sign in", class: "button" %>
<% end %>
<p>New user? <%= link_to "Sign up now!", signup_path %></p>
Routes
Blog::Application.routes.draw do
get "sessions/new"
get "users/new"
resources :posts
resources :static_pages
resources :users
resources :sessions
root to: 'posts#index'
match '/signin', to: 'sessions#new'
match '/signup', to: 'users#new'
match '/signout', to: 'sessions#destroy', via: :delete
match '/about', to: 'static_pages#about'
match '/projects', to: 'static_pages#projects'
end
Also here is the rake:routes
sessions_new GET /sessions/new(.:format) sessions#new
users_new GET /users/new(.:format) users#new
posts GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post GET /posts/new(.:format) posts#new
edit_post GET /posts/:id/edit(.:format) posts#edit
post GET /posts/:id(.:format) posts#show
PUT /posts/:id(.:format) posts#update
DELETE /posts/:id(.:format) posts#destroy
static_pages GET /static_pages(.:format) static_pages#index
POST /static_pages(.:format) static_pages#create
new_static_page GET /static_pages/new(.:format) static_pages#new
edit_static_page GET /static_pages/:id/edit(.:format) static_pages#edit
static_page GET /static_pages/:id(.:format) static_pages#show
PUT /static_pages/:id(.:format) static_pages#update
DELETE /static_pages/:id(.:format) static_pages#destroy
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
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
root / posts#index
signin /signin(.:format) sessions#new
signup /signup(.:format) users#new
signout DELETE /signout(.:format) sessions#destroy
about /about(.:format) static_pages#about
projects /projects(.:format) static_pages#projects
Sessions Helper
module SessionsHelper
def sign_in(user)
cookies.permanent[:remember_token] = user.remember_token
self.current_user = user
end
def current_user=(user)
#current_user = user
end
def current_user
#current_user ||= User.find_by_remember_token(cookies[:remember_token])
end
def signed_in?
!current_user.nil?
end
def sign_out
self.current_user = nil
cookies.delete(:remember_token)
end
end
Based on your view markup, it looks like you should be looking for..
params[:email].downcase, instead of params[:session][:email].downcase.
The form tag isn't scoped to a session object so the params aren't matching correctly. Drop the session in the params code and you should be ok.

RoR: what do I add to routes.rb for this to work?

I have an application where a user can make microposts. But enter one into the form and press post, it says No route matches [POST] "/users/1". Here is my current routes.rb file .
SampleApp::Application.routes.draw do
resources :users do
resources :comments
member do
get :following, :followers
end
end
resources :sessions, only: [:new, :create, :destroy]
resources :microposts, only: [:create, :destroy] do
resources :comments
end
resources :relationships, only: [:create, :destroy]
root to: 'static_pages#home'
match '/signup', to: 'users#new'
match '/signin', to: 'sessions#new'
match '/signout', to: 'sessions#destroy', via: :delete
match '/help', to: 'static_pages#help'
match '/about', to: 'static_pages#about'
match '/contact', to: 'static_pages#contact'
# The priority is based upon order of creation:
and this is the output when I run rake routes:
user_comments GET /users/:user_id/comments(.:format) comments#index
POST /users/:user_id/comments(.:format) comments#create
new_user_comment GET /users/:user_id/comments/new(.:format) comments#new
edit_user_comment GET /users/:user_id/comments/:id/edit(.:format) comments#edit
user_comment GET /users/:user_id/comments/:id(.:format) comments#show
PUT /users/:user_id/comments/:id(.:format) comments#update
DELETE /users/:user_id/comments/:id(.:format) comments#destroy
following_user GET /users/:id/following(.:format) users#following
followers_user GET /users/:id/followers(.:format) users#followers
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
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
sessions POST /sessions(.:format) sessions#create
new_session GET /sessions/new(.:format) sessions#new
session DELETE /sessions/:id(.:format) sessions#destroy
micropost_comments GET /microposts/:micropost_id/comments(.:format) comments#index
POST /microposts/:micropost_id/comments(.:format) comments#create
new_micropost_comment GET /microposts/:micropost_id/comments/new(.:format) comments#new
edit_micropost_comment GET /microposts/:micropost_id/comments/:id/edit(.:format) comments#edit
micropost_comment GET /microposts/:micropost_id/comments/:id(.:format) comments#show
PUT /microposts/:micropost_id/comments/:id(.:format) comments#update
DELETE /microposts/:micropost_id/comments/:id(.:format) comments#destroy
microposts POST /microposts(.:format) microposts#create
micropost DELETE /microposts/:id(.:format) microposts#destroy
relationships POST /relationships(.:format) relationships#create
relationship DELETE /relationships/:id(.:format) relationships#destroy
root / static_pages#home
signup /signup(.:format) users#new
signin /signin(.:format) sessions#new
signout DELETE /signout(.:format) sessions#destroy
help /help(.:format) static_pages#help
about /about(.:format) static_pages#about
contact /contact(.:format) static_pages#contact
I guess what I really need is for [POST] users/:id to route to microposts#create, but I don't know the syntax for it.
p.s. If I add post post "users/:id", :controller => "users/update", I get the error:
ArgumentError (missing :action):
config/routes.rb:4:in `block (2 levels) in <top (required)>'
config/routes.rb:2:in `block in <top (required)>'
config/routes.rb:1:in `<top (required)>'
here is the form which is talking to the controller (i think)
<%= form_for :micropost do |f| %>
<div class="field no-indent">
<%= f.text_area :content, placeholder: "What's something else you want to buy?" %>
<%= hidden_field_tag 'micropost[kind]', "purchase" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
In your form_for you just need to specify url. I think this should work.
<%= form_for :micropost, :html => {:method => :post, :url => microposts_path} do |f| %>
<div class="field no-indent">
<%= f.text_area :content, placeholder: "What's something else you want to buy?" %>
<%= hidden_field_tag 'micropost[kind]', "purchase" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
Also let me know what is html output. In form_for :html parameter is given as a hashmap, where key are form attributes and values are attribute values.
Thanks

Rails routing using destroy action

In my app, comments belong to photos and I am trying to add a method to destroy a comment.
routes.rb
resources :photos do
resources :comments
end
CommentsController
def destroy
#comment = Comment.find(params[:id])
#comment.destroy
end
photos/show.html.erb
<% #photo.comments.each do |comment| %>
<%= comment.body %></p>
<p><%= link_to 'Remove comment', comment, :confirm => 'Are you sure you want to remove this comment? This cannot be undone.', :method => :delete %></p>
<% end %>
The error I get is undefined method 'comment' for #<Photo:0x10ace9270>.
I think I may not have my routes setup correctly because when I check the routes for comment I get:
rake routes | grep comment
photo_comments GET /photos/:photo_id/comments(.:format) {:action=>"index", :controller=>"comments"}
POST /photos/:photo_id/comments(.:format) {:action=>"create", :controller=>"comments"}
new_photo_comment GET /photos/:photo_id/comments/new(.:format) {:action=>"new", :controller=>"comments"}
edit_photo_comment GET /photos/:photo_id/comments/:id/edit(.:format) {:action=>"edit", :controller=>"comments"}
photo_comment GET /photos/:photo_id/comments/:id(.:format) {:action=>"show", :controller=>"comments"}
PUT /photos/:photo_id/comments/:id(.:format) {:action=>"update", :controller=>"comments"}
DELETE /photos/:photo_id/comments/:id(.:format) {:action=>"destroy", :controller=>"comments"}
Anyone have thoughts as to where I went wrong here? Thanks.
<% #photo.comments.each do |comment| %>
<%= comment.body %></p>
<p><%= link_to 'Remove comment', [#photo, comment], :confirm => 'Are you sure you want to remove this comment? This cannot be undone.', :method => :delete %></p>
<% end %>

Forgotten Password in Rails

I am trying to implement a forgotten password solution in rails. I have a form for the user to enter the email address for their registered account, and I intend to have a mailer email them a unique URL that will link them to a password reset page.
My config/routes.rb file has the following routes:
resources :users do
collection do
get :lost_password #the account-email submisison form url
get :reset_password #a url for the function that sends the response email
end
end
When I run rake routes from the console, I get the paths I want:
lost_password_users GET /users/lost_password(.:format) {:action=>"lost_password", :controller=>"users"}
reset_password_users GET /users/reset_password(.:format) {:action=>"reset_password", :controller=>"users"}
users GET /users(.:format) {:action=>"index", :controller=>"users"}
POST /users(.:format) {:action=>"create", :controller=>"users"}
BUT! When the user hits the submit button on the form outlined in the code below:
<h3>Reset Password</h3>
<%= form_for(:user, :url => reset_password_users_path) do |f| %>
<p>Enter the email address you used to register for this site.</p></br>
<div class="field">
<%= f.label :email %> </br>
<%= f.text_field :email %>
</div>
<div class="actions">
<%= f.submit "Send Email" %>
</div>
<% end %>
I get a
No route matches
"/users/reset_password"
error through the ActionController.
I do, in fact, have views and controller functions defined for both the lost_password_users_path and the reset_password_users_path, so I'm puzzled as to why I would run into this routing error.
I have two questions:
Why would the ActionController raise this error, when I clearly have the path, methods, and views defined?
Has anyone else implemented a password reset in RoR, and can you lend any insight as to whether or not this approach is good practice?
Thanks in advance!
Try changing get :reset_password to post :reset_password in routes.rb
function of reset password: I hope,it will be work, use in controller update function
if params[:user][:password].present?
puts "present"
puts params[:current_password]
if (params[:user][:password] == "")
params[:user].delete(:password)
else
if #user.valid_password?(params[:current_password])
#updated = true
puts #updated.to_s
#user.update_attributes(user_params)
sign_in(#user,:bypass => true)
flash[:notice] = "Password Updated Successfully"
redirect_back fallback_location: user_url
else
#updated = false
puts #updated.to_s
flash[:danger] = "Current Password does not matched"
redirect_back fallback_location: user_url
end
end