How to delete multiple checked records in rails? - ruby-on-rails

I figured out how to display checkbox for each row.
The problem is that I can't find out how to write form_tag and submit tag in order to pass the checked rows parameter to messages_controller with using detele action.
and what to write in delete action.
Please help me out!
My view is
<table>
<tr>
<th>delete</th>
<th>ID</th>
<th>Read</th>
<th>Date</th>
<th>Sender</th>
<th>Subject</th>
</tr>
<% #messages.each do |m| %>
<tr>
<td><%= check_box_tag '', m.id, false, class: 'delete_multiple_checkbox', name: "conversations[]" %>
<td><%= m.last_message.id %></td>
<td><%= 'unread' if m.is_unread?(current_user) %></td>
<td><%= m.last_message.created_at %></td>
<td><%= m.last_sender.username %></td>
<td><%= m.subject %></td>
</tr>
<% end %>
</table>
and controller should be something like this( according to this here https://github.com/frodefi/rails-messaging/blob/master/app/controllers/messaging/messages_controller.rb)
def trash
conversation = Conversation.find_by_id(params[:id])
if conversation
current_user.trash(conversation)
flash[:notice] = "Message sent to trash."
else
conversations = Conversation.find(params[:conversations])
conversations.each { |c| current_user.trash(c) }
flash[:notice] = "Messages sent to trash."
end
redirect_to messages_path(box: params[:current_box])
end
route.rb
Example::Application.routes.draw do
root :to => "top#index"
devise_for :users, :controllers => { :registrations => "registrations" }
get 'girls', :to => 'girls#index', :as => :user_root
match '/girls/comment' => 'girls#comment', :via => :post
get "girls/show"
resources :girls
resources :home
devise_for :users do get 'logout' => 'devise/sessions#destroy' end
resources :girls do
collection do
get 'tag'
end
end
resources :contacts
resources :user_profiles
match 'messages/new/:username', :to => 'messages#new'
get "messages/sent"
get "messages/trash"
get "messages/received"
get "messages/show"
get "messages/trash"
match '/messages/deliver' => 'messages#deliver', :via => :post
end

Modify the syntax listed below to fit your requirement:
Model.where(:id => [1,2,3,4,5]).destroy_all
or
Model.where(id: params[:id]).destroy_all

All you have to do is wrap the whole messages rendering block with a form_tag and add a submit_tag wherever you'd like. I assumed your controller is MessagesController under blank namespace and the action is trash. Note that if your controller is under messaging namespace you might want to change the :controller => :messages into :controller => 'messaging/messages'.
<% form_tag :url => { :controller => :messages, :action => :trash}, :method => :delete do %>
<% #messages.each do |m| %>
<tr>
<td><%= check_box_tag '', m.id, false, class: 'delete_multiple_checkbox', name: "conversations[]" %>
<td><%= m.last_message.id %></td>
<td><%= 'unread' if m.is_unread?(current_user) %></td>
<td><%= m.last_message.created_at %></td>
<td><%= m.last_sender.username %></td>
<td><%= m.subject %></td>
</tr>
<% end %>
<%= submit_tag "Trash All Checked" %>
<% end %>
I also assumed your routes.rb accepts a HTTP DELETE method for the specified route. You can check that with rake route | grep messages and verify the route is set.
If it is not you will have to add it with:
resources :messages do
collection do
delete :trash
end
end

Related

form not updating for specific record rails

I'm trying to update a record with a button, by having and admin user tyoe confirm a record by clicking the confirm submit button with this form, but it would just update the first record in the database, not the specific one. Can i put "hour.id" in the form_for section to make it update the record i want it to?
index.html.erb form view
<% #allhours.each do |hour| %>
<tr id="dashfield">
<td><%= hour.user.first_name + " " +hour.user.last_name %></td>
<td><%= hour.assignment %></td>
<td><%= hour.hours %></td>
<td><%= hour.supervisor %></td>
<td><%= hour.date %></td>
<td><%= link_to "confirm", edit_hour_path(hour.id, :status => 'confirmed')%></td>
</tr>
<% end %>
Controller
def index
#allhours = HourLog.where(status:'pending')
end
def update
#hour = HourLog.find_by(status:'pending')
#hour.update_attribute(update_hour_params)
redirect_to '/dashboard/hours'
end
def edit
#hour = HourLog.find(params[:id])
#hour.update_attributes(update_hour_params)
redirect_to '/dashboard/hours'
end
hour_log model
class HourLog < ActiveRecord::Base
belongs_to :user
end
routes
Rails.application.routes.draw do
root 'welcome#index'
get '/signup' => 'users#new'
resources :users
get '/dashboard/users' => 'users#index'
put '/dashboard/users' => 'users#update'
get '/login' => 'sessions#new'
post '/login' => 'sessions#create'
delete '/logout' => 'sessions#destroy'
get '/dashboard' => 'hours#new'
get '/dashboard/hours' => 'hours#index'
put '/dashboard/hours' => 'hours#update'
resources :hours
Thanks!
This line :
#hour = HourLog.find_by(status:'pending')
will find the first Hourlog that is in pending status. You should pass the hourlog id in the form and use it in the controller
change the line in the routes :
put '/dashboard/hours/:id' => 'hours#update'
in the view :
<%= form_tag dashboard_hours_path(id:hour.id), method: :put do %>
<%= hidden_field_tag :role, :value => 'confirm'%>
<%= submit_tag 'Confirm'%>
<% end %>
in the controller :
#hour = HourLog.find(params[:id])

Rails link_to the records of a instance variable .count() result

I have records in my Submitter model being shown in Application Index view being displayed in a table like below. Only I want to be able to click on the number that's listed for the .count() and be taken to my Tickets Index view with all of the corresponding records (Tickets) listed.
I'm having trouble understanding how I can link instance variables to a controller's action, in order to use the layout of my views.
Any ideas?
<table>
<tr>
<th>Name</th>
<th>Number of Tickets</th>
</th>
<tr>
<% Submitter.where(:school_id => current_user.school_id, :disabled => false).each do |sub| %>
<td><%= link_to sub.full_name, edit_submitter_path(sub) %></td>
<td><%= Ticket.where(:submitter_id => sub).count %></td>
</tr>
<% end %>
</table>
routes.rb
resources :feedbacks
resources :products
get "password_resets/new"
get 'signup', to: 'users#new', as: 'signup'
get 'login', to: 'sessions#new', as: 'login'
get 'logout', to: 'sessions#destroy', as: 'logout'
resources :users
resources :sessions
resources :password_resets
resources :mailing_lists
resources :submitters
resources :emails
resources :notes
resources :reminders
resources :descriptions
resources :issues
resources :locations
resources :schools
resources :tickets
root :to => "application#index"
It sounds like you have a submitter that has many tickets. If so, you'd show a list of submitters (in the submitters_controller#index method) and count the number of tickets. Then link that number to the tickets_controller#index method. Like this...
routes.rb
resources :submitters do
resources :tickets
end
submitters_controller.rb
class SubmittersController < ApplicationController
def index
#submitters = Submitter.where(:school_id => current_user.school_id, :disabled => false)
end
end
tickets_controller.rb
class TicketsController < ApplicationController
def index
#submitter = Submitter.find(params[:submitter_id])
#tickets = #submitter.tickets
end
end
views/submitters/index.html.erb
<table>
<tr>
<th>Name</th>
<th>Number of Tickets</th>
</th>
<% #submitters.each do |sub| %>
<tr>
<td><%= link_to sub.full_name, edit_submitter_path(sub) %></td>
<td><%= link_to pluralize(sub.tickets.count, 'ticket'), submitter_tickets_path(sub) %></td>
</tr>
<% end %>
</table>
views/tickets/index.html.erb
# This would show a list of tickets and their attributes - possibly linking to a ticket.
Something like this maybe? Not 100% understanding your question.
<table>
<tr>
<th>Name</th>
<th>Number of Tickets</th>
</th>
<tr>
<% Submitter.where(:school_id => current_user.school_id, :disabled => false).each do |sub| %>
<td><%= link_to sub.full_name, edit_submitter_path(sub) %></td>
<td><%= link_to pluralize(sub.tickets.count, 'ticket'), tickets_path %></td>
<% end %>
</tr>
</table>
I, of course, can't give you perfectly working code unless I know what your config/routes.rb looks like, since I don't know what is the method for your Tickets Index view.

How do I route to a new rails controller action

I'm new to Rails and have the encountered this problem.
I have a books_controller where I have defined a new action called download:
def download
#book = Book.find(params[:id])
return send_file #book.get_filepath, :type => 'application/pdf', :filename => #book.get_filename
end
My routes.rb is like:
resources :books
match '/books(/download(/:id))', :controller => "books", :action => "download"
I would like to create a URL like /books/download/10 to call the download action.
I'm not sure how I can create that link. I have tried reading the Rails Guide on routing, but am very confused by it.
I have tried
<td><%= link_to books_download_path(book) %></td>
and it clearly doesn't work.
undefined method `books_download_path' for #<#<Class:0x682ac40>:0x482cad8>
I'd appreciate any help on this.
Thanks
P.S. Maybe /books/10/download makes more sense than /books/download/10
index.html.erb
<table>
<% #recent_books.each do |book| %>
<tr>
<!-- <td><%= image_tag(book.get_thumbnail) %></td> -->
<td><%= truncate(book.get_title, :length => 30) %></td>
<td><%= book.get_author %></td>
<td><%= book.get_summary %></td>
<td><%= truncate(book.get_filename, :length => 30) %></td>
<!-- <td><%= link_to 'Download', book %></td> -->
<td><%= link_to "Download", download_book_path(book) %></td>
</tr>
<% end %>
<table>
routes.rb
Caliberator::Application.routes.draw do
resources :authors
resources :books do
get :download, :on => :member, :to => 'books#download'
end
end
For Rails 3, try this
resources :books do
get :download, :on => :member, :to => 'books#download'
end
Now, in your views, you can use.
<%= link_to 'Download', download_book_path(book) %>
This will generate books/10/download type links.
Try following
match '/books(/download(/:id))', :controller => "books", :action => "download", :as => "books_download"
Ref:- naming_routes
You have to do it like this :
<%= link_to "Download", download_books_path + "/#{book.id}" %>
For rails 3, you should write:
resources :books do
member do
get 'download'
end
end

How to set up routes correctly

I can untrash all the messages checked in index view without any problem.
But in show view, the link generated show the link to /messages/discard.3
this 3 could be ID.
How can I make it work? it should be linked to messages/discard/3
My files are like these
routes.rb
get "messages/received"
get "messages/sent"
get "messages/trash"
get 'messages/:id' => 'messages#show', :as => :show_messages
match 'messages/new/:username', :to => 'messages#new', :as => :new_messages
match 'messages/deliver' => 'messages#deliver', :via => :post
match 'messages/discard' => 'messages#discard', :via => :post, :as => :discard_messages
match 'messages/untrash' => 'messages#untrash', :via => :post
view 1 (index.html.erb)
<%= form_tag(:action=> discard) do %>
<% #messages.each do |m| %>
<tr>
<td><%= check_box_tag "checked_items[#{m.id}]",m.id %></td>
<td><%= m.last_message.id %></td>
<td><%= 'unread' if m.is_unread?(current_user) %></td>
<td><%= m.last_message.created_at %></td>
<td><%= m.last_sender.username %></td>
<td><%= link_to m.subject, show_messages_path(m) %></td>
</tr>
<% end %>
view 2 (show.html.erb)
<%= link_to 'Trash', discard_messages_path(#messages) %>
messages_controller.rb
def discard
conversation = Conversation.find_all_by_id(params[:checked_items].keys)
if conversation
current_user.trash(conversation)
flash[:notice] = "Message sent to trash."
else
conversations = Conversation.find(params[:conversations])
conversations.each { |c| current_user.trash(c) }
flash[:notice] = "Messages sent to trash."
end
redirect_to :back
end
You can try change it to:
match 'messages/discard/:id' => 'messages#discard', :via => :post, :as => :discard_messages
However I think what you should do is to change your all routes to:
resource :messages do
member do
#code
end
collection do
#code
end
end
It's easier to read and maintain

How can I pass the parameters to controller correctly?

From show view: I'd like to pass the shown message's id to discard action and trash the message.
From index view: I'd like to pass the checked messages' ids to discard action and trash them all at once.
But I only can trash one record at once even if I check multiple and submit from index view.
How can I archive both 1 and 2 with the same action????
Routes
match 'messages/discard(/:id)' => 'messages#discard', :via => :post , :as => :discard_messages
index view
<%= form_tag(:action => discard, :via => 'post') do %>
<% #messages.each do |m| %>
<tr>
<td><%= check_box_tag "id",m.id %></td>
<td><%= m.last_message.id %></td>
<td><%= 'unread' if m.is_unread?(current_user) %></td>
<td><%= m.last_message.created_at.to_s(:jp) %></td>
<td><%= m.last_sender.username %></td>
<td><%= link_to m.subject, show_messages_path(:id => m, :breadcrumb => #box) %></td>
</tr>
<% end %>
<%= submit_tag "discard", :class => 'btn' %>
<% end %>
show view
<%= link_to 'Discard', discard_messages_path(#messages), :class => 'btn', :method => 'post' %>
controller
def discard
conversation = Conversation.find_all_by_id(params[:id])
if conversation
current_user.trash(conversation)
flash[:notice] = "Message sent to trash."
else
conversations = Conversation.find(params[:conversations])
conversations.each { |c| current_user.trash(c) }
flash[:notice] = "Messages sent to trash."
end
redirect_to :back
end
use the [] naming in your html, which rails will then make available as an array in the params
index.html.erb
<td><%= check_box_tag "message_id[]", m.id %></td>
controller
# ...
else
conversations = Conversation.where("id IN (?)", params[:message_id][])
# ...
to simplify things further I would remove the conditional in your action and create two separate actions
routes
resource :messages do
member do
post 'discard' # /messages/:id/discard
end
collection do
post 'discard_all' # /messages/discard_all?message_id[]=1&message_id[]=22
end
end

Resources