Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialAnastasios Christopoulos
Courses Plus Student 55 PointsNeed help with a ruby on rails bike rental application
I've got the application partially working using devices to authenicate and then user can selects the bike he wants and add it to the class.
User goes back and adds it again to extend the duration.
Want to add a calendar functionality with the start and end date user needs to select.
This then to go to a booking controller which will record all the rentals and update the bikes availability.
class CartController < ApplicationController
before_action :authenticate_user!
def add
# get the ID of the product
id = params[:id]
# if the cart is already been created, use the existing cart
# else create a blank cart
if session[:cart] then
cart = session[:cart]
else
session[:cart] = {}
cart = session[:cart]
end
# if the product has already been added to the cart, increment the value
# else set the value to 1
if cart[id] then
cart[id] = cart[id] + 1
else
cart[id] = 1
end
# redirect to the cart display page
redirect_to :action => :index
end
def clearCart
# set the session variable to nil and redirect
session[:cart] = nil
redirect_to :action => :index
end
def index
# if there is a cart, pass it to the page for display
# else pass an empty value
if session[:cart] then
@cart = session[:cart]
else
@cart = {}
end
end
end
class ItemsController < ApplicationController
before_action :authenticate_user!
before_action :ensure_admin, :only => [:edit, :destroy]
before_action :set_item, only: [:show, :edit, :update, :destroy]
# GET /items Only admin can edit delete items
# GET /items.json
def index
@items = Item.all
end
# GET /items/1
# GET /items/1.json
def show
end
# GET /items/new
def new
@item = Item.new
end
# GET /items/1/edit
def edit
end
# POST /items
# POST /items.json
def create
puts "debug +++++++++++++++++++++++++++++++++++++++++++++++++++"
puts params.inspect
puts "debug +++++++++++++++++++++++++++++++++++++++++++++++++++"
@item = Item.new(item_params)
respond_to do |format|
if @item.save
format.html { redirect_to @item, notice: 'Item was successfully created.' }
format.json { render :show, status: :created, location: @item }
else
format.html { render :new }
format.json { render json: @item.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /items/1
# PATCH/PUT /items/1.json
def update
respond_to do |format|
if @item.update(item_params)
format.html { redirect_to @item, notice: 'Item was successfully updated.' }
format.json { render :show, status: :ok, location: @item }
else
format.html { render :edit }
format.json { render json: @item.errors, status: :unprocessable_entity }
end
end
end
# DELETE /items/1
# DELETE /items/1.json
def destroy
@item.destroy
respond_to do |format|
format.html { redirect_to items_url, notice: 'Item was successfully destroyed.' }
format.json { head :no_content }
end
end
def ensure_admin
unless current_user && current_user.admin?
render :text => "Access Error Message", :status => :unauthorized
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_item
@item = Item.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def item_params
params.require(:item).permit(:title, :description, :price, :image_url, :category, :brand)
end
end
<h1>Your Cart</h1>
<% if @cart.empty? %>
<p>Your Cart is empty</p>
<% end %>
<% total = 0 %>
<table class="cart">
<tr>
<td class="legend"></td>
<td class="legend">Item</td>
<td class="legend">Price</td>
<td class="legend">Length</td>
<td class="legend">Total</td>
</tr>
<% @cart.each do | id, quantity | %>
<% item = Item.find_by_id(id) %>
<tr>
<td>
<div class="image">
<%= link_to (image_tag item.image_url, :style => "height:40px"), item %>
</div>
</td>
<td class="title"><%= link_to item.title, item %></td>
<td class="price"><%= number_to_currency(item.price) %></td>
<td class="quantity"><%= quantity %><br /></td>
<td class="price"><%= number_to_currency(quantity * item.price, :unit => "€") %></td>
%input{:type =>'text', :placeholder => params[:startdate] != nil ? params[:startdate] : "from date", :id => 'startdate', :name => "startdate", :style => 'width: 100px'}
%input{:type =>'text', :placeholder => params[:startdate] != nil ? params[:enddate] : "to date", :id => 'enddate', :name => "enddate", :style => 'width: 100px'}
</tr>
<% total += quantity * item.price %>
<% end %>
<tr>
<td colspan="4">
<div class="total">Total:</div>
</td>
<td>
<div class="price"><%= number_to_currency(total, :unit => "Eur") %></div>
</td>
</tr>
</table>
<p>
<%= link_to 'Make a booking', :controller => :items %>
</p>
routes.rb
Rails.application.routes.draw do
resources :bookings
get 'bookings/index'
get 'bookings/show'
get 'bookings/new'
get 'bookings/edit'
get 'bookings/destroy'
resources :profiles
get 'bookings/index'
get 'bookings/show'
get 'bookings/new'
get 'bookings/edit'
get 'bookings/destroy'
resources :profiles
devise_for :users
get '/about' => 'site#about'
get '/contact' => 'site#contact'
get '/admin' => 'user#admin_login'
get '/logout' => 'user#logout'
get '/cart' => 'cart#index'
get '/cart/:id' => 'cart#add'
get '/cart/clear' => 'cart#clearCart'
get '/signedinuserprofile' => 'profiles#signedinuserprofile'
get '/product' => 'catalog#view'
resources :items
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
root 'items#index'
# Example of regular route:
get 'products/:id' => 'catalog#view'
# Example of named route that can be invoked with purchase_url(id: product.id)
get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
# Example resource route (maps HTTP verbs to controller actions automatically):
# resources :products
# Example resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Example resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Example resource route with more complex sub-resources:
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', on: :collection
# end
# end
# Example resource route with concerns:
# concern :toggleable do
# post 'toggle'
# end
# resources :posts, concerns: :toggleable
# resources :photos, concerns: :toggleable
# Example resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
end
Can you let me know if you have advise.
Thanks
1 Answer
Jay McGavren
Treehouse TeacherHi, Anastasios Christopoulos ,
This is a good start! If I were doing this, I would probably create a Booking
model that has_many :items
. You can add an attribute to a model with a type of date
or datetime
to store a date. Try this (either in your main app or a separate test app) to see some example code, complete with a date/time picker:
bin/rails g scaffold Booking date:datetime