Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/assets/javascripts/progresses.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
3 changes: 3 additions & 0 deletions app/assets/stylesheets/progresses.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Place all the styles related to the Progresses controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
4 changes: 2 additions & 2 deletions app/controllers/goals_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class GoalsController < ApplicationController
# GET /goals
# GET /goals.json
def index
@goals = Goal.all
@goals = Goal.includes(:progresses).all
end

# GET /goals/1
Expand Down Expand Up @@ -71,6 +71,6 @@ def set_goal

# Never trust parameters from the scary internet, only allow the white list through.
def goal_params
params.require(:goal).permit(:name)
params.require(:goal).permit(:name, :benchmark)
end
end
74 changes: 74 additions & 0 deletions app/controllers/progresses_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
class ProgressesController < ApplicationController
before_action :set_progress, only: [:show, :edit, :update, :destroy]

# GET /progresses
# GET /progresses.json
def index
@progresses = Progress.all
end

# GET /progresses/1
# GET /progresses/1.json
def show
end

# GET /progresses/new
def new
@progress = Progress.new
end

# GET /progresses/1/edit
def edit
end

# POST /progresses
# POST /progresses.json
def create
@progress = Progress.new(progress_params)

respond_to do |format|
if @progress.save
format.html { redirect_to @progress, notice: 'Progress was successfully created.' }
format.json { render :show, status: :created, location: @progress }
else
format.html { render :new }
format.json { render json: @progress.errors, status: :unprocessable_entity }
end
end
end

# PATCH/PUT /progresses/1
# PATCH/PUT /progresses/1.json
def update
respond_to do |format|
if @progress.update(progress_params)
format.html { redirect_to @progress, notice: 'Progress was successfully updated.' }
format.json { render :show, status: :ok, location: @progress }
else
format.html { render :edit }
format.json { render json: @progress.errors, status: :unprocessable_entity }
end
end
end

# DELETE /progresses/1
# DELETE /progresses/1.json
def destroy
@progress.destroy
respond_to do |format|
format.html { redirect_to progresses_url, notice: 'Progress was successfully destroyed.' }
format.json { head :no_content }
end
end

private
# Use callbacks to share common setup or constraints between actions.
def set_progress
@progress = Progress.find(params[:id])
end

# Never trust parameters from the scary internet, only allow the white list through.
def progress_params
params.require(:progress).permit(:goal_id, :points, :entry_date)
end
end
2 changes: 2 additions & 0 deletions app/helpers/progresses_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module ProgressesHelper
end
3 changes: 3 additions & 0 deletions app/models/goal.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# frozen_string_literal: true

class Goal < ApplicationRecord
has_many :progresses

validates :benchmark, numericality: true
end
5 changes: 5 additions & 0 deletions app/models/progress.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class Progress < ApplicationRecord
belongs_to :goal
validates :points, numericality: true
validates :entry_date, presence: true
end
33 changes: 33 additions & 0 deletions app/queries/progress_query.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
class ProgressQuery

attr_accessor :goal

def initialize(goal)
raise ArgumentError, 'Goal parameter is invalid' unless goal.is_a? Goal

@goal = goal
end

##
# Return progresses in the past 7 days
#
# @author Ming
def week_entries
entries = goal.progresses.where('entry_date > ?', Date.today - 1.week)
Array.new(7) do |i|
entry = entries.find { |e| e[:entry_date] == Date.today - i.days }
entry&.points
end
end

##
# Return weekday string array for the past 7 days
#
# @author Ming
def self.weekdays
Array.new(7) do |i|
(Date.today - i.days).strftime('%A').first(3)
end
end

end
3 changes: 3 additions & 0 deletions app/views/goals/_form.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
.field
= f.label :name, class: 'label'
.control= f.text_field :name, placeholder: f.object.class.human_attribute_name(:name), class: 'input'
.field
= f.label :benchmark, class: 'label'
.control= f.number_field :benchmark, placeholder: f.object.class.human_attribute_name(:benchmark), class: 'input', step: :any

.field.is-grouped
p.control
Expand Down
12 changes: 12 additions & 0 deletions app/views/goals/index.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ table.table
thead
tr
th Name
- ProgressQuery.weekdays.each do |day|
th = day
th
th
th
Expand All @@ -12,10 +14,20 @@ table.table
- @goals.each do |goal|
tr
td = goal.name
- ProgressQuery.new(goal).week_entries.each do |entry|
td
- if entry.nil?
'-
- elsif entry.to_f >= goal.benchmark
span.tag.is-success = entry
- else
span.tag.is-danger = entry
td = link_to 'Show', goal
td = link_to 'Edit', edit_goal_path(goal)
td = link_to 'Destroy', goal, data: { confirm: 'Are you sure?' }, method: :delete

br

= link_to 'New Goal', new_goal_path
'|
= link_to 'New Progress', new_progress_path
19 changes: 19 additions & 0 deletions app/views/progresses/_form.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
= form_for @progress do |f|
- if @progress.errors.any?
#error_explanation
h2 = "#{pluralize(@progress.errors.count, "error")} prohibited this progress from being saved:"
ul
- @progress.errors.full_messages.each do |message|
li = message

.field
= f.label :goal, class: 'label'

.control= f.collection_select :goal_id, Goal.order(:name), :id, :name, {}, { class: 'input' }
.field
= f.label :points, class: 'label'
.control= f.number_field :points, placeholder: f.object.class.human_attribute_name(:points), class: 'input', step: :any
.field
= f.label :entry_date, class: 'label'
.control= f.date_field :entry_date, placeholder: f.object.class.human_attribute_name(:entry_date), class: 'input'
.actions = f.submit
2 changes: 2 additions & 0 deletions app/views/progresses/_progress.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
json.extract! progress, :id, :goal_id, :points, :entry_date, :created_at, :updated_at
json.url progress_url(progress, format: :json)
8 changes: 8 additions & 0 deletions app/views/progresses/edit.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
h1 Editing progress

== render 'form'

=> link_to 'Show', @progress
'|
=< link_to 'Back', progresses_path

25 changes: 25 additions & 0 deletions app/views/progresses/index.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
h1 Listing progresses

table.table
thead
tr
th Goal
th Points
th Entry date
th
th
th

tbody
- @progresses.each do |progress|
tr
td = progress.goal
td = progress.points
td = progress.entry_date
td = link_to 'Show', progress
td = link_to 'Edit', edit_progress_path(progress)
td = link_to 'Destroy', progress, data: { confirm: 'Are you sure?' }, method: :delete

br

= link_to 'New Progress', new_progress_path
1 change: 1 addition & 0 deletions app/views/progresses/index.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
json.array! @progresses, partial: 'progresses/progress', as: :progress
5 changes: 5 additions & 0 deletions app/views/progresses/new.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
h1 New progress

== render 'form'

= link_to 'Back', progresses_path
15 changes: 15 additions & 0 deletions app/views/progresses/show.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
p#notice = notice

p
strong Goal:
= @progress.goal
p
strong Points:
= @progress.points
p
strong Entry date:
= @progress.entry_date

=> link_to 'Edit', edit_progress_path(@progress)
'|
=< link_to 'Back', progresses_path
1 change: 1 addition & 0 deletions app/views/progresses/show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
json.partial! "progresses/progress", progress: @progress
8 changes: 8 additions & 0 deletions app/views/shared/_error_messages_for.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
- if obj.errors.any?
div.notification.is-danger
button.delete
h3= "Please fix the following #{pluralize(obj.errors.count, 'error')} "
ul
- obj.errors.full_messages.each do |msg|
li= msg

8 changes: 0 additions & 8 deletions app/views/shared/error_messages_for.html.slim

This file was deleted.

1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: true

Rails.application.routes.draw do
resources :progresses
resources :goals
root to: 'goals#index'
end
7 changes: 7 additions & 0 deletions db/migrate/20190307192121_add_benchmark_to_goal.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class AddBenchmarkToGoal < ActiveRecord::Migration[5.2]
def change
add_column :goals, :benchmark, :float
# NOTE: SQLite won't allow null: false constraint in add column clause
change_column :goals, :benchmark, :float, null: false
end
end
11 changes: 11 additions & 0 deletions db/migrate/20190307192431_create_progresses.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class CreateProgresses < ActiveRecord::Migration[5.2]
def change
create_table :progresses do |t|
t.references :goal, foreign_key: true
t.float :points
t.date :entry_date, null: false

t.timestamps
end
end
end
24 changes: 17 additions & 7 deletions db/schema.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# frozen_string_literal: true

# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
Expand All @@ -12,10 +10,22 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20_180_815_015_756) do
create_table 'goals', force: :cascade do |t|
t.string 'name'
t.datetime 'created_at', null: false
t.datetime 'updated_at', null: false
ActiveRecord::Schema.define(version: 2019_03_07_192431) do

create_table "goals", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.float "benchmark", null: false
end

create_table "progresses", force: :cascade do |t|
t.integer "goal_id"
t.float "points"
t.date "entry_date", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["goal_id"], name: "index_progresses_on_goal_id"
end

end
4 changes: 2 additions & 2 deletions test/controllers/goals_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class GoalsControllerTest < ActionDispatch::IntegrationTest

test 'should create goal' do
assert_difference('Goal.count') do
post goals_url, params: { goal: { name: @goal.name } }
post goals_url, params: { goal: { name: @goal.name, benchmark: @goal.benchmark } }
end

assert_redirected_to goal_url(Goal.last)
Expand All @@ -36,7 +36,7 @@ class GoalsControllerTest < ActionDispatch::IntegrationTest
end

test 'should update goal' do
patch goal_url(@goal), params: { goal: { name: @goal.name } }
patch goal_url(@goal), params: { goal: { name: @goal.name, benchmark: @goal.benchmark } }
assert_redirected_to goal_url(@goal)
end

Expand Down
Loading