Skip to content

Instantly share code, notes, and snippets.

@neves
Last active October 1, 2019 11:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neves/e3ffc49e1c7f9abf83e7adf41928416d to your computer and use it in GitHub Desktop.
Save neves/e3ffc49e1c7f9abf83e7adf41928416d to your computer and use it in GitHub Desktop.
class RentDaysController < ApplicationController
before_action :set_rent_day, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
skip_before_action :verify_authenticity_token
# GET /rent_days
# GET /rent_days.json
def index
@rent_days = RentDay.all
end
# GET /rent_days/1
# GET /rent_days/1.json
def show
end
# GET /rent_days/new
def new
@rent_day = RentDay.new
end
# GET /rent_days/1/edit
def edit
end
# POST /rent_days
# POST /rent_days.json
def create
@rent_day = RentDay.new(rent_day_params)
respond_to do |format|
if @rent_day.save
format.html { redirect_to @rent_day, notice: 'Rent day was successfully created.' }
format.json { render :show, status: :created, location: @rent_day }
else
format.html { render :new }
format.json { render json: @rent_day.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /rent_days/1
# PATCH/PUT /rent_days/1.json
def update
respond_to do |format|
if @rent_day.update(rent_day_params)
format.html { redirect_to @rent_day, notice: 'Rent day was successfully updated.' }
format.json { render :show, status: :ok, location: @rent_day }
else
format.html { render :edit }
format.json { render json: @rent_day.errors, status: :unprocessable_entity }
end
end
end
# DELETE /rent_days/1
# DELETE /rent_days/1.json
def destroy
@rent_day.destroy
respond_to do |format|
format.html { redirect_to rent_days_url, notice: 'Rent day was successfully destroyed.' }
format.json { head :no_content }
end
end
# CUSTOM METHODS
# esta lógica de Business está misturada com responsabilidade do controller,
# de capturar input e gerar output.
# Seria melhor extrair para um Service.
def availability
# não informou o motivo da falha
if params[:date].empty? && params[:days].empty?
return render json: :fail
end
# não tratou data inválida
start_date = Date.strptime(params[:date], '%Y-%m-%d')
end_date = start_date + (params[:days].to_i).days
days = params[:days].to_i
# off by one error
# (caso o cliente queira alugar por 1 dia,
# 0..1 na verdade faz 2 loops, 1 para o zero e outro para o 1
(0..days).each do |i|
day_plus_one = start_date + i.days
check_date = RentDay.find_by_start_date(day_plus_one)
unless check_date.nil?
return render json: :fail
# break depois do return?
break
end
end
# ruby não precisa de return, qualquer editor com lint já pega isso
return render json: :ok
end
# esta lógica de Business está misturada com responsabilidade do controller,
# de capturar input e gerar output.
# Seria melhor extrair para um Service.
def make_reservation
# não tratou data inválida
start_date = Date.strptime(params[:date], '%Y-%m-%d')
end_date = start_date + (params[:days].to_i).days
days = params[:days].to_i
# mesmo off-by-one error do método acima
(0..days).each do |i|
day_plus_one = start_date + i.days
# não utilizou transaction da maneira correta,
# ela deve estar fora do loop
RentDay.transaction do
RentDay.create(start_date: day_plus_one , end_date: end_date, days: days, user_id: current_user.id)
# forçar rollback desfaz o create acima
raise ActiveRecord::Rollback
end
end
# porque não utilizar os ids dos registros criados acima?
number = order_number 6
# ruby não precisa de return
return render json: {ok: :ok , order_number: number }
end
def order_number number
# sugestão 1: rand(36**number).to_s(36)
# sugestão 2: SecureRandom seria mais seguro
charset = Array('A'..'Z') + Array('a'..'z')
Array.new(number) { charset.sample }.join
end
def history
@history = current_user.rent_days.order(:start_date)
end
private
# Use callbacks to share common setup or constraints between actions.
def set_rent_day
@rent_day = RentDay.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def rent_day_params
params.require(:rent_day).permit(:start_date, :end_date, :days)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment