list all user's objects - ruby-on-rails

as the title says I'm trying to list all cars of one specific user, also each car has two options show and update
as you see in the picture, my problem is when I want to show or edit the selected car, it routes (look the bottom left of the image) it takes all the ids of all the cars for example users/"id"/cars/"id1"/"id2" instead to take the id of the specific car: users/"id"/cars/"id1"/
here is te index.html.erb file:
<div class="container">
<h1>Listing Cars</h1>
<table class="table table-condensed">
<tr>
<th>Brand</th>
<th>Color</th>
<th>Model</th>
<th>Year</th>
<th></th>
<th></th>
</tr>
<% #car.each do |car| %>
<tr>
<td><%= car.brand %></td>
<td><%= car.color %></td>
<td><%= car.model %></td>
<td><%= car.year %></td>
<td><%= link_to 'Show', user_car_path(#user,#car) %></td>
<td><%= link_to 'Edit', edit_user_car_path(#user, #car) %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New car', new_user_car_path, :class => "btn btn-primary" %>
</div>
and whether you need the car controller:
class CarsController < ApplicationController
def new
#user = User.find(params[:user_id])
#car = #user.cars.build
end
def create
#user = User.find(params[:user_id])
#car = #user.cars.build(params[:car])
if #car.save
redirect_to user_car_path(#user, #car), :flash => { :notice => " car created!" }
else
redirect_to new_user_car_path ,:flash => { :notice => " sorry try again :(" }
end
end
def show
#user = User.find(params[:user_id])
#car = #user.cars.find(params[:id])
#redirect_to user_car_path(#user, #car)
end
def index
#user = User.find(params[:user_id])
#car = #user.cars.all
end
def edit
#user = User.find(params[:user_id])
#car = #user.cars.find(params[:id])
#redirect_to user_car_path(#user, #car)
end
def update
#user = User.find(params[:user_id])
#car = #user.cars.find(params[:id])
if #car.update_attributes(params[:car])
redirect_to user_cars_path, :flash => { :notice => " Car Updated!" }
else
render 'edit'
end
end
end

Inside a Ruby enumerator, the block variable is each member of the enumerator, one after the other. So if, in your sample code, #cars is ["Toyota", "Mazda", "Honda"], then car will be first "Toyota", then "Mazda", then "Honda".
This is a long way of saying you're using the instance variable when you should be using the block variable. ;) Correct your code to look like this:
<% #car.each do |car| %>
<tr>
<td><%= car.brand %></td>
<td><%= car.color %></td>
<td><%= car.model %></td>
<td><%= car.year %></td>
<td><%= link_to 'Show', user_car_path(#user, car) %></td>
<td><%= link_to 'Edit', edit_user_car_path(#user, car) %></td>
</tr>
<% end %>
It should be car, not #car, in your routes.

Related

How to show only scoped instances of Task model in view

I'm building a Task Manager in Rails. I used scope to get all instances of a Task model that are due today. The scope on the Task model works and is returning only Tasks due today when calling due_today on Tasks in the Rails console. But I can't seem to show these Tasks due today in the view. Do I need to add a conditional?
This is my views index.html.erb
<p id="notice"><%= notice %></p>
<h1>Team's Tasks</h1>
<table>
<thead>
<tr>
<th>Task title</th>
<th>Description</th>
<th>Date assigned</th>
<th>Due date</th>
<th>Overdue?</th>
<th>Completed?</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #tasks.each do |task| %>
<tr>
<td><%= task.title %></td>
<td><%= task.description %></td>
<td><%= task.created_at %></td>
<td><%= task.duedate %></td>
<td><%= task.overdue? %></td>
<td><%= task.completed %></td>
<td><%= link_to 'Show', task %></td>
<td><%= link_to 'Edit', edit_task_path(task) %></td>
<td><%= link_to 'Destroy', task, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<h1>Tasks due today.</h1>
<table>
<thead>
<tr>
<th>Task title</th>
<th>Description</th>
<th>Date assigned</th>
<th>Due date</th>
<th>Overdue?</th>
<th>Completed?</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #tasks.due_today.each do |task| %>
<tr>
<td><%= task.title %></td>
<td><%= task.description %></td>
<td><%= task.created_at %></td>
<td><%= task.duedate %></td>
<td><%= task.overdue? %></td>
<td><%= task.completed %></td>
<td><%= link_to 'Show', task %></td>
<td><%= link_to 'Edit', edit_task_path(task) %></td>
<td><%= link_to 'Destroy', task, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<p>
<%= link_to 'New Task', new_task_path %>
</p>
this is my Task model
class Task < ApplicationRecord
#use scope on Task model to mark overdue Tasks if the present date is greater than duedate.
scope :overdue, -> { where("duedate < ?", Time.now) }
#use scope on Task model to get only tasks that are due today.
scope :due_today, ->{ where("duedate >= ? AND duedate <= ?", Date.current.beginning_of_day, Date.current.end_of_day) }
end
This is the controller
class TasksController < ApplicationController
before_action :set_task, only: %i[ show edit update destroy ]
# GET /tasks or /tasks.json
# Order all tasks by ascending order
def index
#tasks = Task.all.order(duedate: :asc)
end
# GET /tasks/1 or /tasks/1.json
def show
end
# GET /tasks/new
def new
#task = Task.new
end
# GET /tasks/1/edit
def edit
end
# POST /tasks or /tasks.json
def create
#task = Task.new(task_params)
respond_to do |format|
if #task.save
format.html { redirect_to #task, notice: "Task was successfully created." }
format.json { render :show, status: :created, location: #task }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /tasks/1 or /tasks/1.json
def update
respond_to do |format|
if #task.update(task_params)
format.html { redirect_to #task, notice: "Task was successfully updated." }
format.json { render :show, status: :ok, location: #task }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: #task.errors, status: :unprocessable_entity }
end
end
end
# DELETE /tasks/1 or /tasks/1.json
def destroy
#task.destroy
respond_to do |format|
format.html { redirect_to tasks_url, notice: "Task was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_task
#task = Task.find(params[:id])
end
# Only allow a list of trusted parameters through.
def task_params
params.require(:task).permit(:title, :description, :duedate, :completed)
end
end
I assume you have a TasksController and an index method there.
try following in the index method
def index
#tasks = Task.due_today
end
let me know if this works
You need to change due_date scope.. use between or date_trunc method.
where("date_trunc('day', duedate)::date = ?", Date.today)
let me know if it works
Got it to work. No changes to the controller. None needed. This is the code.
This is the Task model.
class Task < ApplicationRecord
#use scope on Task model to mark overdue Tasks if the present date is greater than duedate.
scope :overdue, -> { where("duedate < ?", Time.now) }
#use scope on Task model to get Tasks due today.
scope :due_today, ->{ where("duedate >= ? AND duedate <= ?", Date.current.beginning_of_day, Date.current.end_of_day) }
def overdue?
duedate < Time.now
end
def due_today?
duedate >= Date.current.beginning_of_day && duedate <= Date.current.end_of_day
end
end
This is the Task view.
<p id="notice"><%= notice %></p>
<h1>Team Task Manager</h1>
<table>
<thead>
<tr>
<th>Task</th>
<th>Description</th>
<th>Date assigned</th>
<th>Due date</th>
<th>Overdue?</th>
<th>Completed?</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #tasks.each do |task| %>
<tr>
<td><%= task.title %></td>
<td><%= task.description %></td>
<td><%= task.created_at %></td>
<td><%= task.duedate %></td>
<td><%= task.overdue? %></td>
<td><%= task.completed %></td>
<td><%= link_to 'Show', task %></td>
<td><%= link_to 'Edit', edit_task_path(task) %></td>
<td><%= link_to 'Destroy', task, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<br>
<h1>DUE TODAY!</h1>
<table>
<thead>
<tr>
<th>Task</th>
<th>Description</th>
<th>Date assigned</th>
<th>Due date</th>
<th>Overdue?</th>
<th>Completed?</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #tasks.due_today.each do |task| %>
<tr>
<td><%= task.title %></td>
<td><%= task.description %></td>
<td><%= task.created_at %></td>
<td><%= task.duedate %></td>
<td><%= task.overdue? %></td>
<td><%= task.completed %></td>
<td><%= link_to 'Show', task %></td>
<td><%= link_to 'Edit', edit_task_path(task) %></td>
<td><%= link_to 'Destroy', task, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<p>
<%= link_to 'New Task', new_task_path %>
</p>

book a user id with a role (instructor) whilst logged in as a user as a role of (admin or student)

I am trying to book an instructor whilst logged in as a student (user).
log in MODEL is User with optional roles of [Instructor] [Student] [Admin].
I keep getting this error
undefined method `id' for #
error message
The button is giving me the error..
How do I declare the instructors user_id to be booked whilst logged in as a user such as student
instructors_controller.rb
# GET /instructors
# GET /instructors.json
def index
##instructors = Instructor.all
#instructor_users = User.where(role: 'instructor')
end
Instructor/index
<h1>List Instructors</h1>
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Role</th>
</tr>
<% #instructor_users.each do |user| %>
<tr>
<td><%= user.id %></td>
<td><%= user.name %></td>
<td><%= user.role %></td>
<td>
<%= button_to 'Book a Lesson', {controller: 'lessons', action: 'new', id: #user.id } , {class: "button-to"} %>
</td>
</tr>
<% end %>
</table>
<br>
lessons_controller.rb
def new
if logged_in?
##lesson = Lesson.new
#lesson = Lesson.new(user_id: params[:id], name: User.find(session[:user_id]).name
session[:return_to] = nil
else
session[:return_to] = request.url
redirect_to login_path, alert: " 'You need to login to book a lesson' "
end
end
# POST /lessons
# POST /lessons.json
def create
#lesson = Lesson.new(lesson_params)
if #lesson.save
instructor = User.find(#instructor.user.id)
redirect_to lesson, notice: 'Lesson was successfully created.'
else
render :new
end
end
change
#instructor_user.id
to
user.id
because #instructor_users.each do |user| to user

Running into undefined method from model class in view

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

Rails syntax error </div>

I am trying to set "edit" function for a simple CMS. I can make it to create/delete, but it just won't let me "edit".
here is the error message:
SyntaxError in SectionsController#edit
app/views/sections/edit.html.erb:42: syntax error, unexpected keyword_ensure, expecting keyword_end
Extracted source (around line #42):
40
41
when I checked my edit.html.erb. it seems fine?
'index'}, :class => 'back-link') %>
<div class="sections edit">
<h2>Update Sections</h2>
<%= form_for(:two, :url => {:action => 'update', :id => #one.id}) do |f| %>
<table summary="Section form fields">
<% #one.each do |f| %>
<tr>
<th>Name</th>
<td><%= f.text_field(:name) %></td>
</tr>
<tr>
<th>Position</th>
<td><%= f.text_field(:position) %></td>
</tr>
<tr>
<th>Visible</th>
<td><%= f.text_field(:visible) %></td>
</tr>
<tr>
<th>content_type</th>
<td><%= f.text_field(:content_type) %></td>
</tr>
<tr>
<th>content</th>
<td><%= f.text_field(:content) %></td>
</tr>
<tr>
<th>page_id</th>
<td><%= f.text_field(:page_id) %></td>
</tr>
</table>
<div class="form-buttons">
<%= submit_tag("Update Section") %>
</div>
<% end %>
</div>
Here is the controller:
class SectionsController < ApplicationController
def index
#one = Section.all
end
def show
#one = Section.find(params[:id])
end
def new
#one = Section.new
end
def create
#one = Section.new(section_params)
if #one.save
flash[:notice] = "Section created successfully!"
redirect_to(:action => 'index')
else
render('new')
end
end
def edit
#one = Section.find(params[:id])
end
def update
#one = Section.find(params[:id])
if #one.update_attributes(section_params)
flash[:notice] = "Subject updated successfully!"
redirect_to(:action => 'show', :id =>#one.id)
else
render('edit')
end
end
def delete
#one = Section.find(params[:id])
end
def destroy
subject = Section.find(params[:id]).destroy
flash[:notice] = "Subject deleted successfully!"
redirect_to(:action => 'index')
end
private
def section_params
params.require(:two).permit(:id,:name,:position,:visible,:page_id,:content,:content_type)
end
end
Thanks so much!!
Thanks #Pavan, #MarsAtomic and #Mandeep ! I found the issue: <% #one.each do |f| %>. I don't really need this line. If I need it, I need a end code for this.
In my case, I don't, so I go ahead deleted this line, and it worked now!
thanks again everyone!

Nested class is saving but not displaying correctly.

I'm working through the rails intro guide but using 'stocks' instead of 'articles' and 'time_detlas' instead of 'comments' my issue is that it seems to be saving time_deltas correctly, I think I checked that correctly but the show of the stock just adds an extra blank row to the table of time_deltas no numbers show. Any suggestions why?
Stocks controller:
class StocksController < ApplicationController
def new
#stock = Stock.new
end
def index
#stocks = Stock.all
end
def create
# XXX Add columns for delta and current standing when we get there
# they can intiate to nil
#stock = Stock.new(stock_params)
if #stock.save
redirect_to #stock
else
render 'new'
end
end
def show
#stock = find_stock
#time_delta = #stock.time_deltas.build
end
def edit
#stock = find_stock
end
def update
#stock = find_stock
if #stock.update(stock_params)
redirect_to #stock
else
render 'edit'
end
end
def destroy
#stock = find_stock
#stock.destroy
redirect_to stocks_path
end
private
def stock_params
params.require(:stock).permit(:name, :hashtag)
end
def find_stock
return Stock.find(params[:id])
end
end
Time Delta Controller
class TimeDeltasController < ApplicationController
def create
#stock = Stock.find(params[:stock_id])
#time_delta = #stock.time_deltas.create(time_delta_params)
redirect_to stock_path(#stock)
end
private
def time_delta_params
params.require(:time_delta).permit(:start, :length)
end
end
Show for the stock
<h1> Stock </h1>
<table>
<tr>
<th>Stock</th>
<th>Hashtag</th>
</tr>
<tr>
<td><%= #stock.name %></td>
<td><%= #stock.hashtag %></td>
</tr>
</table>
<h3>TimeDeltas: </h2>
<table>
<tr>
<th>Start</th>
<th>Length</th>
</tr>
<% #stock.time_deltas.each do |time_delta| %>
<tr>
<td><%= #time_delta.start %></td>
<td><%= #time_delta.length %></td>
</tr>
<% end %>
</table>
<h3>Add a TimeDelta:</h2>
<%= form_for([#stock, #stock.time_deltas.build]) do |f| %>
<p>
<%= f.label :start %><br>
<%= f.text_field :start %>
</p>
<p>
<%= f.label :length %><br>
<%= f.text_field :length %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Back', stocks_path%>
<%= link_to 'Edit', edit_stock_path(#stock)%>
Any help is appreciated, thank you!
just remove # from time_delta
<% #stock.time_deltas.each do |time_delta| %>
<tr>
<td><%= time_delta.start %></td>
<td><%= time_delta.length %></td>
</tr>
<% end %>
up
You need # only to be able to share this var with your view. Eg: If you add this to your show action: #time_deltas = TimeDelta.all
you can show time_deltas in your view.
like:
<% #time_deltas.each do |td|%>
<%= td.start%>
<% end %>

Resources