the delete method is not working when trying to destroy a record. When clicking on the button, it will redirect me to shops#show action, looks like the method: :delete is not working...Any help please?
Routes
resources :shops
HTML
<% #shops.sort.each do |shop| %>
<tr>
<td><%= shop.name %></td>
<td><%= shop.email %></td>
<td><%= shop.direction %></td>
<td>
<%= link_to '<button>Borrar</button>', shop, method: :delete, data: { confirm: "Seguro?" } %>
</td>
</tr>
<% end %>
Controller
def destroy
#shop = Shop.find(params[:id])
#shop.destroy
respond_to do |format|
format.html { redirect_to "/sushiadmin", notice: 'Se ha editado la tienda.' }
format.json { head :no_content }
end
end
Do this:
<%= link_to 'Borrar', shop, method: :delete, data: { confirm: "Seguro?" }, class: 'btn btn-primary' %>
And delete Shop.find
def destroy
#shop.destroy
respond_to do |format|
format.html { redirect_to "/sushiadmin", notice: 'Se ha editado la tienda.' }
format.json { head :no_content }
end
end
Try with this (specifying the url)
link_to '<button>Borrar</button>' , shop_path( shop ), :method => 'delete', data: { confirm: "Seguro?" }
Acording with http://apidock.com/rails/ActionView/Helpers/UrlHelper/link_to
link_to(body, url, html_options = {})
Related
I am new to Ruby on Rails and I am making a view page showing a table from the database. I want to add a link_to to delete this record. I tried the code written below and nothing worked for me.
The browser keeps refreshing and does nothing.
ruby 3.1.2
Rails 7.0.4
<%= link_to 'Delete', #friend, data: {turbo_method: :delete, turbo_confirm: 'Sure?'}, class: "btn btn-danger" %>
also with this
<%= link_to 'Delete', #friend, method: :delete, data: { confirm: 'Are you sure?' }, class: "btn btn-danger" %>
html.erb code
<p style="color: green"><%= notice %></p>
<%= render #friend %>
<div>
<%= link_to "Edit this friend", edit_friend_path(#friend) %> |
<%= link_to "Back to friends", friends_path %>
<%#= button_to "Destroy this friend", #friend, method: :delete,data: {turbo_confirm: 'Are you sure?'} %>
<%#= button_to "Destroy this friend", #friend, method: :delete,data: {turbo_confirm: 'Are you sure?'} %>
<%= link_to 'Delete', #friend, method: :delete, data: { confirm: 'Are you sure?' }, class: "btn btn-danger" %>
</div>
Controller code
class FriendsController < ApplicationController
before_action :set_friend, only: %i[ show edit update destroy ]
# GET /friends or /friends.json
def index
#friends = Friend.all
end
# GET /friends/1 or /friends/1.json
def show
end
# GET /friends/new
def new
#friend = Friend.new
end
# GET /friends/1/edit
def edit
end
# POST /friends or /friends.json
def create
#friend = Friend.new(friend_params)
respond_to do |format|
if #friend.save
format.html { redirect_to friend_url(#friend), notice: "Friend was successfully created." }
format.json { render :show, status: :created, location: #friend }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #friend.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /friends/1 or /friends/1.json
def update
respond_to do |format|
if #friend.update(friend_params)
format.html { redirect_to friend_url(#friend), notice: "Friend was successfully updated." }
format.json { render :show, status: :ok, location: #friend }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #friend.errors, status: :unprocessable_entity }
end
end
end
# DELETE /friends/1 or /friends/1.json
def destroy
#friend.destroy
respond_to do |format|
format.html { redirect_to friends_url, notice: "Friend was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_friend
#friend = Friend.find(params[:id])
end
# Only allow a list of trusted parameters through.
def friend_params
params.require(:friend).permit(:first_name, :last_name, :email, :phone, :twitter)
end
end
Your code should work
<%= link_to 'Delete', #friend,
data: {turbo_method: :delete, turbo_confirm: 'Sure?'}, class: "btn btn-danger" %>
But more reliable to use button_to that generate form tag with button
<%= button_to 'Delete', #friend,
method: :delete, form: {data: {turbo_confirm: 'Sure?'}}, class: "btn btn-danger" %>
I have a list of movie categories displayed on my home page. Along with this, I have displayed the list of ALL the movies currently available in the db. When the user clicks on one of the categories, I would like to re-render the containing the list of ALL movies to show ONLY the list of movies that belong to the category that the user selected.
I use link_to to display the list of categories. The link_to would be routed to a controller function which loads the movies that belong Only to the category selected by the user. Then a js.erb would be invoked with this generated list which would in-turn invoke a Rails partial.
The Rails partial would re-render the complete movie list to display ONLY the movies that belong to the selected category. The javascript and partial are getting invoked all right but the partial fails to re-render the list. Am not sure what I'm missing here.
app/views/movies/index.html.erb
<% #categories.each do |category| %>
<tr><td>
<%= link_to category, show_category_url(:genre => category), :remote => true %> <%end%>
<%if false %>
<%= link_to show_category_url, :remote => true do %>
category
<%end %>
</td></tr>
<% end %>
<div id="#movies_list">
<% #movies.each do |movie| %>
<tr>
<td><%= movie.title %></td>
<td><%= movie.category %> </td>
<td><%= movie.rating %></td>
<% if !current_user.nil? %>
<% if movie.user.email == current_user.email %>
<td><%= link_to 'Show', movie, :class => "btn btn-primary"%></td>
<td><%= link_to 'Edit', edit_movie_path(movie), :class => "btn btn-primary" %></td>
<td><%= link_to 'Destroy', movie, method: :delete, data: { confirm: 'Are you sure?' }, :class => "btn btn-primary" %></td>
<% end %>
<% end %>
</tr>
<% end %>
</div>
app/views/movies/show.js.erb
$("#movies_list").html("<%= escape_javascript(render("show_category")) %>");
app/views/movies/_show_categories.html.erb
<% #movies_in_category.each do |movie| %>
<tr>
<td><%= movie.title %></td>
<td><%= movie.rating %></td>
<% puts "************** movies/show_category"%>
<% puts movie.title %>
<% if false %>
<td>
<%= form_for #rating do |rating_form| %>
<%= rating_form.number_field :rating, class: 'rating', 'data-size' => 'xs'%>
<%= rating_form.submit 'Add', class: 'btn btn-primary btn-success' %>
<% end %>
</td>
<% end %>
<% if !current_user.nil? %>
<% if movie.user.email == current_user.email %>
<td><%= link_to 'Show', movie, :class => "btn btn-primary"%></td>
<td><%= link_to 'Edit', edit_movie_path(movie), :class => "btn btn-primary" %></td>
<td><%= link_to 'Destroy', movie, method: :delete, data: { confirm: 'Are you sure?' }, :class => "btn btn-primary" %></td>
<% end %>
<% end %>
</tr>
<% end%>
My partial is getting invoked all right but the re-rendering of div movies_list does not happen.
This is my controller code:
class MoviesController < ApplicationController
before_action :set_movie, only: [:show, :edit, :update, :destroy]
#before_action :authenticate_user!
# GET /movies
# GET /movies.json
def index
#movies = Movie.all
$all_movies = #movies
#categories = #movies.uniq.pluck(:category)
#movies_by_category = Hash.new
#categories.each do |category|
#movies_by_category[category] = Movie.where(:category => category).length
end
end
# GET /movies/1
# GET /movies/1.json
def show
respond_to do |format|
format.js {render layout: false}
puts "############## moviescontroller/show_category"
end
end
# GET /movies/new
def new
#movie = current_user.movies.new
end
# GET /movies/1/edit
def edit
end
# POST /movies
# POST /movies.json
def create
#movie = current_user.movies.new(movie_params)
respond_to do |format|
if #movie.save
format.html { redirect_to #movie, notice: 'Movie was successfully created.' }
format.json { render :show, status: :created, location: #movie }
else
format.html { render :new }
format.json { render json: #movie.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /movies/1
# PATCH/PUT /movies/1.json
def update
respond_to do |format|
if #movie.update(movie_params)
format.html { redirect_to #movie, notice: 'Movie was successfully updated.' }
format.json { render :show, status: :ok, location: #movie }
else
format.html { render :edit }
format.json { render json: #movie.errors, status: :unprocessable_entity }
end
end
end
# DELETE /movies/1
# DELETE /movies/1.json
def destroy
#movie.destroy
respond_to do |format|
format.html { redirect_to movies_url, notice: 'Movie was successfully destroyed.' }
format.json { head :no_content }
end
end
def show_category
category_selected = params[:genre]
#all_movies = Movie.all
#movies_in_category = Movie.where(category: category_selected)
puts "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
puts category_selected
puts #movies_in_category.length
end
def login
end
private
# Use callbacks to share common setup or constraints between actions.
def set_movie
#movie = Movie.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def movie_params
params.require(:movie).permit(:title, :category, :rating)
end
end
The reason is,
<div id="#movies_list">
contents goes here..
</div>
You shouldn't add # when defining id attribute for an element, That will be used when selecting an HTML element based on the selector. So remove #
<div id="movies_list">
contents goes here..
</div>
I am making a blog application and when the user is viewing the post index view I want them to only edit and delete posts they have created. I am getting the following error:
undefined method `user_id' for nil:NilClass
views/posts/index.html
<td><% if current_user.id == #post.user_id %></td>
<td><%= link_to 'Edit', edit_post_path(#post) %></td>
<td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% end %>
The above is my if statement that allows user to only edit and delete posts they have created.
create method in post_controller:
def create
#post = Post.new(post_params)
#post.user = current_user
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
form
at.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
I do a before action filter for the edit, update and destroy action:
before_action :correct_user, only: [:edit, :update, :destroy]
def correct_user
#post = Post.find_by(id: params[:id]) // find the post
unless current_user?(#post.user)
redirect_to user_path(current_user)
end
end
current_user?(#post.user) this checks if the current_user and the #post.user that you defined when you create a new post are the same.
In my sessionHelper I have to methods for defining the current user:
def current_user?(user)
user == current_user
end
def current_user
if(user_id = session[:user_id])
#current_user ||= User.find_by(id: user_id)
end
end
In your post view you have to add conditional code to render the edit and delete links only if the user is the correct one:
<% if current_user?(post.user) %>
<%= link_to "Edit", edit_micropost_path(micropost) %>
<%= link_to "Delete", micropost, method: :delete, data: { confirm: "Do you want to delete this post ?"}%>
<% end %>
you want to make sure that the if statement is out side of the TD tag
<% if current_user && current_user.id == #post.user_id %>
<td></td>
<td><%= link_to 'Edit', edit_post_path(#post) %></td>
<td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% end %>
#Post Controller
class Post < ApplicationController
...
def show
#post = Post.find(params[:id])
end
...
end
While I was working trying to code my views, I noticed that my code that was previously rendering on the index view is now only showing the first two lines of code on my local server, and I don't understand why.
Here is my index.html.erb code:
<h1>All Bookmarks</h1>
<%= link_to 'Create a New Bookmark', new_bookmark_path %>
<table>
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<div class="row">
<div class="col-md-8">
<tbody>
<% #bookmarks.each do |bookmark| %>
<div class="media">
<div class="media-body">
<h4 class="media-heading">
<tr>
<td><%= link_to bookmark.url, "http://#{bookmark.url}" %></td>
<td><%= link_to 'Show', bookmark %></td>
<td><%= link_to 'Edit', edit_bookmark_path(bookmark) %></td>
<td><%= link_to 'Destroy', bookmark, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
And here is my bookmark controller code:
class BookmarksController < ApplicationController
before_action :set_bookmark, only: [:show, :edit, :update, :destroy]
def index
#bookmarks = Bookmark.all
end
def show
end
def new
#bookmark = Bookmark.new
end
def edit
end
def create
bookmark = Bookmark.where(url: params[:bookmark][:url]).first
#bookmark = bookmark.present? ? bookmark : Bookmark.new(bookmark_params)
if #bookmark.save
#bookmark.users << current_user
Rails.logger.info ">>>>>>>>>>>>> Bookmark: #{#bookmark.inspect}"
topic_names = params[:topic_names].split(' ')
topic_names.each do |topic_name|
name = topic_name.sub(/#/, '')
#bookmark.topics << Topic.find_or_create_by_name(name)
end
respond_to do |format|
format.html { redirect_to #bookmark, notice: 'Bookmark was successfully created.' }
format.json { render action: 'show', status: :created, location: #bookmark }
end
else
respond_to do |format|
format.html { render action: 'new' }
format.json { render json: #bookmark.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #bookmark.update(bookmark_params)
format.html { redirect_to #bookmark, notice: 'Bookmark was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #bookmark.errors, status: :unprocessable_entity }
end
end
end
def destroy
#bookmark.destroy
respond_to do |format|
format.html { redirect_to bookmarks_url }
format.json { head :no_content }
end
end
private
def set_bookmark
#bookmark = Bookmark.find(params[:id])
end
def bookmark_params
params.require(:bookmark).permit(:url)
end
end
Any thoughts?
It seems that your html is invalid. You are using div tags in rails loop, which is not being closed. The other thing is that non-table related html tags can be used only inside tags.
This might be the working solution.
<h1>All Bookmarks</h1>
<%= link_to 'Create a New Bookmark', new_bookmark_path %>
<table>
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<% #bookmarks.each do |bookmark| %>
<tr>
<td><%= link_to bookmark.url, "http://#{bookmark.url}" %></td>
<td><%= link_to 'Show', bookmark %></td>
<td><%= link_to 'Edit', edit_bookmark_path(bookmark) %></td>
<td><%= link_to 'Destroy', bookmark, method: :delete, data: { confirm: 'Are you sure?' } %> </td>
</tr>
<% end %>
</tbody>
</table>
Hope that helps.
I'm new to Ruby, Rails and programming in general, so please forgive me if the question is very trivial.
I have this view:
<h1>Listing products</h1>
<table>
<tr>
<th>\</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #products.each do |product| %>
<tr>
<td><%= product.\ %></td>
<td><%= link_to 'Show', product %></td>
<td><%= link_to 'Edit', edit_product_path(product) %></td>
<td><%= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New Product', new_product_path %>
When I try to access the link http://localhost:3000/products I receive an error:
SyntaxError in Products#index
Showing C:/Sites/depot/app/views/products/index.html.erb where line #13 raised:
C:/Sites/depot/app/views/products/index.html.erb:13: syntax error, unexpected $undefined
...tput_buffer.append= ( product.\ );#output_buffer.safe_concat...
... ^
C:/Sites/depot/app/views/products/index.html.erb:18: syntax error, unexpected keyword_end, expecting ')'
'); end
^
C:/Sites/depot/app/views/products/index.html.erb:25: syntax error, unexpected keyword_ensure, expecting ')'
C:/Sites/depot/app/views/products/index.html.erb:27: syntax error, unexpected keyword_end, expecting ')'
Extracted source (around line #13):
10:
11: <% #products.each do |product| %>
12: <tr>
13: <td><%= product.\ %></td>
14: <td><%= link_to 'Show', product %></td>
15: <td><%= link_to 'Edit', edit_product_path(product) %></td>
16: <td><%= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' } %></td>
Trace of template inclusion: app/views/products/index.html.erb
I was just following an example in a book to learn Rails, so basically I've done nothing to code this view.
Can someone point me to the right direction?
You need to put <%= product.name %> (substitute in desired attribute) instead of <%= product.\ %>
The little tiny caret under the the incorrect syntax gives you an indication of what is tripping the error.
Rewrite the code # app\views\products\index.html.erb" as follows:
<h1>Listing products</h1>
<table>
<% #products.each do |product| %>
<tr class="<%= cycle('list_line_odd', 'list_line_even') %>">
<td>
<%= image_tag(product.image_url, class: 'list_image') %>
</td>
<td class="list_description">
<dl>
<dt><%= product.title %></dt>
<dd><%= truncate(strip_tags(product.description),
length: 80) %></dd>
</dl>
</td>
<td class="list_actions">
<%= link_to 'Show', product %><br/>
<%= link_to 'Edit', edit_product_path(product) %><br/>
<%= link_to 'Destroy', product, method: :delete,
data: { confirm: 'Are you sure?' } %>
</td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New product', new_product_path %>
Rewrite the code # app\controllers\products_controller.rb as follows:
class ProductsController < ApplicationController
# GET /products
# GET /products.json
def index
#products = Product.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #products }
end
end
# GET /products/1
# GET /products/1.json
def show
#product = Product.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #product }
end
end
# GET /products/new
# GET /products/new.json
def new
#product = Product.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #product }
end
end
# GET /products/1/edit
def edit
#product = Product.find(params[:id])
end
# POST /products
# POST /products.json
def create
#product = Product.new(params[:product])
respond_to do |format|
if #product.save
format.html { redirect_to #product,
notice: 'Product was successfully created.' }
format.json { render json: #product, status: :created,
location: #product }
else
format.html { render action: "new" }
format.json { render json: #product.errors,
status: :unprocessable_entity }
end
end
end
# PUT /products/1
# PUT /products/1.json
def update
#product = Product.find(params[:id])
respond_to do |format|
if #product.update_attributes(params[:product])
format.html { redirect_to #product,
notice: 'Product was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #product.errors,
status: :unprocessable_entity }
end
end
end
# DELETE /products/1
# DELETE /products/1.json
def destroy
#product = Product.find(params[:id])
#product.destroy
respond_to do |format|
format.html { redirect_to products_url }
format.json { head :no_content }
end
end
end
rails generates very useful logs. Read it once it gives you line number and file name.
replace <%= product.\%> with <%= product.name %> where name is the attribute of product.