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])
Related
Now I am trying to set a form on the page of index.html.erb(members). I want the form to show the result of searching and want it not to move to other pages. I want to show the result on index.html.erb(members) itself.
But the code below makes the application move to show.html(members) after pushing the search button. I have no idea why this happens. Could you give me some advice?
Now I am trying to set search window based on my textbook. But I failed with the error message below. I don't understand the cause although this is just a syntax error. Could you give me some advice?
☆index.html.erb(members controller)
<h1>Listing users</h1>
<p>※登録されているメンバーのリストです。</p>
<%= form_tag :action => 'index' do %>
<div class = "field">
<%= label_tag 'place', '活動場所:' %><br />
<%= text_field_tag 'place' %>
</div>
<%= submit_tag '検索' %>
<% end %>
<%= #places_field %>
☆members controller
def index
if !checklogin? then return end #
#members = Member.all
#places_field = Member.where("place = ?", params[:place])
respond_to do |format|
format.html # index.html.erb
format.json
end
end
☆routes.rb
MiniSNS::Application.routes.draw do
resources :group_message_comments
resources :group_messages do
resources :group_message_comments
end
root :to => 'members#login'
match '/groups/join'
resources :group_messages
resources :groups do
resources :group_messages
end
match '/members/new'
resources :index
resources :groups
post 'groups/:id' => 'group#show'
post '/groups/new'
post '/index/index'
match '/members/login'
match '/members/logout'
match '/members/friend'
match '/members/show'
post '/messages/comment'
resources :comments
resources :messages
resources :friends
resources :members
#OmniAuth
match "/auth/:provider/callback" => "sessions#callback"
match "/logout" => "sessions#destroy", :as => :logout
match '/auth/failure', to: redirect('/')
First, you have to adding remote => true on your submit_tag like:
<%= submit_tag '検索', :remote => true %>
Then on your controller, adding return to js with:
respond_to do |format|
format.html # index.html.erb
format.json
format.js
end
Create new view called index.js.erb and fill that file with Javascript code to update your place field, the simplest way is like:
On index.html.erb make sure you have this kind of code:
<div id="place_field_section"><%= render 'place_field' %></div>
Of course you should have a partial called _place_field.html.erb for example:
<table>
<tr>
<th>Foo</th>
<th>Bar</th>
</tr>
<% #place_fields.each do |place_field| %>
<tr>
<td><%= place_field.foo %></td>
<td><%= place_field.bar %></td>
</tr>
<% end %>
</table>
then on your index.js.erb:
$("#place_field_section").html("<%= escape_javascript(render('place_field')) %>");
Is this what you intent to? Please correct me if I'm wrong.
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
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
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
I'm currently making a website in Rails that will allow the user to create and account and then when logged in he/she will be get a list of all the "rooms" in the database. And then the user will be able to book a one of the rooms. Like a booking system.
So first when the user logges in it will get redirected to the controller booker index. That will get all the rooms from the database and display the information in a table.
The model situation is built up like the User has_many reservations, and the reservation belongs_to User.
So what I want to do is that next to the table (can be on the same row) there should be a click button. And when the user click the button the reservations is created and linked to the user without leaving the current page.
Atm this is what I came up with (in the index.html.erb)
<%= form_for(#new_reservation) do |new_res| %>
<% #all_rooms.each do |r| %>
<tr>
<td><%= r.room %></td>
<td><%= r.room_size %></td>
<td><%= r.building %></td>
<td><%= r.room_description %></td>
<td><%= new_res.submit "Create" %></td>
</tr>
<% end %>
<% end %>
and my controller looks like
class BookerController < ApplicationController
before_action :require_user, only: [:index, :show]
def index
#new_reservation = Reservation.new
#all_rooms = Room.all
end
def create
end
end
and route
Rails.application.routes.draw do
#Log in / Logout functionality
get '/login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
#The start screen
root 'welcome#index'
#The signup
get '/signup' => 'users#new'
get '/book' => 'booker#index'
resources :users
resources :reservations
You need a few things to make this happen:
If you want your user to stay on the page, you need to make your form
asynchronous with remote: true
If you want to create the Reservation in your BookerController#create method, it needs to be accessible with a HTTP POST
A simple, straightforward way to do this is to have in your view a form for each potential reservation the user might do
Working example:
app/views/booker/index.html.erb
<% #all_rooms.each do |r| %>
<tr>
<td><%= r.room_size %></td>
<td><%= r.building %></td>
<td><%= r.room_description %></td>
<td>
<%= form_for(Reservation.new, remote: true, format: :js, url: {controller: "booker", action: "create"}) do |new_res| %>
<%= new_res.hidden_field :room_id, value: r.id %>
<%= new_res.hidden_field :user_id, value: current_user.id %>
<%= new_res.submit "Book" %>
<% end %>
</td>
</tr>
<% end %>
Here, replace current_user.id by whatever gives you the currently logged in user
app/controllers/booker_controller.rb
class BookerController < ApplicationController
def index
#all_rooms = Room.all
end
def create
new_reservation = Reservation.new(reservation_params)
new_reservation.save
respond_to do |format|
format.json { head :no_content }
end
end
private
def reservation_params
params.require(:reservation).permit(:room_id, :user_id)
end
end
app/config/routes.rb
Rails.application.routes.draw do
get '/book' => 'booker#index'
post '/book' => 'booker#create'
end
And when the user click the button the reservations is created and linked to the user without leaving the current page.
You need to learn up on how to make Ajax request in Rails.
http://ericlondon.com/2014/03/13/rails-4-submit-modal-form-via-ajax-and-render-js-response-as-table-row.html
Basically you will need to something like this
<%= form_for(#new_reservation, remote: remote) do |new_res| %>
Which will send data asynchronosly, you will create the reservation , and render a view for display