project_site model has one attribute submission_status. i want to set that status from index#action for there corresponding row. i want on submit button click on each row to change there correspong submission_status to true. how can i do this in rails 5.
project_sites_controller.rb
def index
#project_sites = current_user.project_sites
end
def new
#project_site = current_user.project_sites.build
end
def create
#project_site = current_user.project_sites.build(project_site_params)
#users = current_user.director_id
#projects = Project.where(user_id: #users)
respond_to do |format|
if #project_site.save
format.html { redirect_to project_sites_url, notice: 'Attendance was successfully Uploaded.' }
format.json { render :show, status: :created, location: #project_site }
else
format.html { render :new }
format.json { render json: #project_site.errors, status: :unprocessable_entity }
end
end
end
def update
#users = current_user.director_id
#projects = Project.where(user_id: #users)
respond_to do |format|
if #project_site.update(project_site_params)
format.html { redirect_to project_sites_url, notice: 'Attendance was successfully updated.' }
format.json { render :show, status: :ok, location: #project_site }
else
format.html { render :edit }
format.json { render json: #project_site.errors, status: :unprocessable_entity }
end
end
end
index.html.erb
<table>
<thead>
<tr>
<th>Uploaded Date</th>
<th>Attendance File</th>
<th>Submit Attendance</th>
</tr>
</thead>
<tbody>
<% #project_sites.each do |project_site| %>
<tr>
<td><%= project_site.created_at.strftime('%d-%m-%Y') %></td>
<td><%= link_to "View Attendance", project_site.attendance.url, :class => "fi-page-export-csv" %></td>
<td>
<%= form_for ProjectSite.new do |f| %>
<%#f.hidden_field :project_site_id, value: project_site.id%>
<%=f.hidden_field :submission_status, value: true%>
<div>
<%= f.submit 'Submit', :class => 'button primary small float-right' %>
</div>
<% end %>
</tr>
<% end %>
</tbody>
</table>
add a route for an action which set status
#routes.rb
resources :project_sites do
put :set_submission_status, on: :member
end
define action which set status
#submission_status_controller.rb
def set_submission_status
#project_site = ProjectSite.find(params[:id])
#project_site.update(submission_status: true)
redirect_to project_sites_path
end
replace form_for with following link
#view
= link_to set_submission_status_project_site_path(project_site), method: :put
You have to pass the id of project_site for which you want to update the submission_status and on the controller updates the same project_site(id pass as hidden field), for this you need write **ajax** call
<table>
<thead>
<tr>
<th>Uploaded Date</th>
<th>Attendance File</th>
<th>Submit Attendance</th>
</tr>
</thead>
<tbody>
<% #project_sites.each do |project_site| %>
<tr>
<td><%= project_site.created_at.strftime('%d-%m-%Y') %></td>
<td><%= link_to "View Attendance", project_site.attendance.url, :class => "fi-page-export-csv" %></td>
<td>
<%= form_for ProjectSite.new do |f| %>
<%#f.hidden_field :project_site_id, value: project_site.id%>
<%=f.hidden_field :submission_status, value: true%>
<%= f.hidden_field :project_site_id, project_site.id%>
<div>
<%= f.submit 'Submit', :class => 'button primary small float-right' %>
</div>
<% end %>
</tr>
<% end %>
</tbody>
</table>
Related
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 have a method called calculation_of_total_cost in model Tippy
It's running into problems being called in index.html.erb via tippies views directory.
This is the error I receive: undefined method*' for nil:NilClass`
I have googled it, and now understand that it is the result of the one of the variables being nil.
How do I resolve this, i.e, how do I make the method work in index.html.erb? This is index view that I am calling it from, so I need an instance method, not class, right?
Also, addendum: this same method works fine in show.html.erb
show.html.erb
<br/><br/>
<h1 class="text-center">Your Total Cost</h1>
<br/><br />
<table class="table table-striped">
<tr>
<td>
Cost of Your Meal:
</td>
<td>
<%= humanized_money_with_symbol #tippy.cost %>
</td>
</tr>
<tr>
<td>
Tip You Picked:
</td>
<td>
<%= number_to_percentage(#tippy.tip * 100, format: "%n%", precision: 0) %>
</td>
</tr>
<tr>
<td>
The Total Cost:
</td>
<td>
<%= humanized_money_with_symbol #tippy.calculation_of_total_cost %>
</td>
</tr>
</table>
<%= link_to 'New Tippy', new_tippy_path %>
<%= link_to "Index", tippies_path %>
Here is the Tippy model:
class Tippy < ApplicationRecord
validates :tip, presence: true
validates :cost, presence: true
#monetize :tip_cents
monetize :cost_cents, :numericality => {:greater_than => 0}
TIP_CHOICES = { "10%" => ".10", "20%" => ".20", "30%" => ".30", "40%" => ".40", "50%" => ".50",
"60%" => ".60", "70%" => ".70", "80%" => ".80", "90%" => ".90" }
def calculation_of_total_cost
cost + (tip * cost)
end
end
Here is the index.html.erb file
<p id="notice"><%= notice %></p>
<h1>Tippies</h1>
<table>
<thead>
<tr>
<th>Tip</th>
<th>Cost</th>
<th>Total</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #tippies.each do |tippy| %>
<tr>
<td><%= tippy.tip %></td>
<td><%= tippy.cost %></td>
<td><%= tippy.calculation_of_total_cost %></td>
<td><%= link_to 'Show', tippy %></td>
<td><%= link_to 'Edit', edit_tippy_path(tippy) %></td>
<td><%= link_to 'Destroy', tippy, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Tippy', new_tippy_path %>
Tippy Controller
class TippiesController < ApplicationController
#before_action :set_tippy, only: [:show, :edit, :update, :destroy]
# GET /tippies
# GET /tippies.json
def index
#tippies = Tippy.all
end
# GET /tippies/1
# GET /tippies/1.json
def show
##calculation_of_total_cost
end
# GET /tippies/new
def new
#tippy = Tippy.new
end
# GET /tippies/1/edit
def edit
end
# POST /tippies
# POST /tippies.json
def create
#tippy = Tippy.new(tippy_params)
respond_to do |format|
if #tippy.save
format.html { redirect_to #tippy, notice: 'Tippy was successfully created.' }
format.json { render :show, status: :created, location: #tippy }
else
format.html { render :new }
format.json { render json: #tippy.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /tippies/1
# PATCH/PUT /tippies/1.json
def update
respond_to do |format|
if #tippy.update(tippy_params)
format.html { redirect_to #tippy, notice: 'Tippy was successfully updated.' }
format.json { render :show, status: :ok, location: #tippy }
else
format.html { render :edit }
format.json { render json: #tippy.errors, status: :unprocessable_entity }
end
end
end
# DELETE /tippies/1
# DELETE /tippies/1.json
def destroy
#tippy.destroy
respond_to do |format|
format.html { redirect_to tippies_url, notice: 'Tippy was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_tippy
#tippy = Tippy.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def tippy_params
params.require(:tippy).permit(:tip, :cost)
end
end
To solve this problem you need to set a binding.pry or a breakpoint at this line of index.html.erb, so that we can understand in the loop you are executing why tippy is getting value of nil.
You need to install pry gem.
Please also share the values of #tippies and the details of the other variable in the loop that fails, because tippy=nil.
An alternative for pry is just printing the value of the variable in the log with puts tippy.calculation_of_total_cost.
Right now I am guess is that #tippies which includes all #tippy in your tippies table, could have one field that has calculation of total cost = nil. To verifiy this you should check with the debug the value of tippy and of tippy.calculation_of_total_cost in the index.html.erb view.
<% #tippies.each do |tippy| %>
<tr>
<% binding.pry %>
<td><%= tippy.tip %></td>
<td><%= tippy.cost %></td>
<td><%= tippy.calculation_of_total_cost %></td>
<td><%= link_to 'Show', tippy %></td>
<td><%= link_to 'Edit', edit_tippy_path(tippy) %></td>
<td><%= link_to 'Destroy', tippy, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
also it is a good idea to inspect show.html.erb as there it is working.
def calculation_of_total_cost
cost + (tip * cost)
end
I am trying to prepend a recently created post to a list without having to refresh the browser. I am wondering how this can be done with table elements.
index.html.erb
<table class="table table-hover">
<thead>
<tr>
<th>Name</th>
<th>Card image</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody id="content">
<%= render #suggested_invites %>
</tbody>
</table>
_suggested_invite.html.erb
<% #suggested_invites.each do |suggested_invite| %>
<tr style="background-color:<%= suggested_invite.color %>">
<td style="color:white"><%= suggested_invite.name %></td>
<td><img src="<%= suggested_invite.card_image %>" class="img-fluid" id="card_image" alt="Responsive image"></td>
<td><%= link_to 'Edit', edit_suggested_invite_path(suggested_invite), :class => 'action_buttons' %></td>
<td><%= link_to 'De-Activate', suggested_invite, method: :delete, :class => 'action_buttons', data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
suggested_invites_controller.rb
def create
#suggested_invite = SuggestedInvite.new(suggested_invite_params)
respond_to do |format|
if #suggested_invite.save
format.html { redirect_to #suggested_invite, notice: 'Suggested invite was successfully created.' }
format.json { render :show, status: :created, location: #suggested_invite }
format.js
else
format.html { render :new }
format.json { render json: #suggested_invite.errors, status: :unprocessable_entity }
format.js
end
end
end
create.js.erb
$("#mynewsuggestedinvite").modal('hide');
$("#content").prepend('<%= j render #suggested_invite %>');
When I run this code I get a 500 internal server error. I know that it breaks here:
$("#content").prepend('<%= j render #suggested_invite %>');
I have been looking and haven't found any ways of doing this. Any help would be very much appreciated!
To see which error you get, without access to logs you can do this:
begin
$("#content").prepend('<%= j render #suggested_invite %>');
rescue Error => e
<%= raw e.backtrace %>
end
Then check the server response when trying to create
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.
The author built a UPS scaffold and rails created the model as up instead of ups. I've hacked some solutions in to make it work, but I can't get the create method to work when called from the new form. Rails calls the index function and no new object is created.
ups_controller.rb
def create
#up = Ups.new(params[:up])
respond_to do |format|
if #up.save
format.html { redirect_to #up, notice: 'Up was successfully created.' }
format.json { render json: #up, status: :created, location: #up }
else
format.html { render action: "new" }
format.json { render json: #up.errors, status: :unprocessable_entity }
end
end
end
def new
#up = Ups.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #up }
end
end
ups/form.html.erb
<%= form_for(#up) do |f| %>
<table class="table table-striped table-bordered">
<tr>
<th>name</th>
<td><%= f.text_field :name %></td>
</tr>
<tr>
<th>attr</th>
<td><%= f.select :attr_id, options_from_collection_for_select(Attr.order(:name).where(:major => true).all, "id", "name", #up.attr_id) %></td>
</tr>
<tr>
<th>Action</th>
<td><%= f.submit "Submit New UPS" %></td>
</tr>
</table>
<% end %>
routes.rb
resources :ups
match 'ups/create' => 'ups#create'
match 'ups/index' => 'ups#index'
match 'pdus/link_all_ups' => 'pdus#link_all_ups'
Here is the button that calls the new method of the ups_controller:
<%= link_to 'Enter New UPS', new_ups_path, :class => "btn btn-success pull-right" %>
rake routes
ups GET /ups(.:format) ups#index
POST /ups(.:format) ups#create
new_up GET /ups/new(.:format) ups#new
edit_up GET /ups/:id/edit(.:format) ups#edit
up GET /ups/:id(.:format) ups#show
PUT /ups/:id(.:format) ups#update
DELETE /ups/:id(.:format) ups#destroy
ups_index /ups/index(.:format) ups#index
Thanks for any advice.
You also want to make sure rails is sending a Post request like this:
<%= form_for #up, :url=> ups_path, :method => :post do |f| %>
My guess is that your url is correct but rails in sending it as a get instead of a post. As you can see from your routes, the index and create action both have the same url and the only difference is the get/post.
ups GET /ups(.:format) ups#index
POST /ups(.:format) ups#create