diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..7e9ace1
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,17 @@
+FROM ruby:2.3.1
+
+RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
+RUN mkdir /app
+WORKDIR /app
+
+# Cache Dependency Install
+ADD Gemfile /app/Gemfile
+ADD Gemfile.lock /app/Gemfile.lock
+RUN bundle install
+
+# Add Repository
+ADD . /app
+
+# Run Server
+EXPOSE 3000
+CMD rake db:migrate && rails server -b 0.0.0.0
diff --git a/Gemfile b/Gemfile
index 6f350ef..315908f 100644
--- a/Gemfile
+++ b/Gemfile
@@ -3,8 +3,7 @@ source 'https://rubygems.org'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.0.0', '>= 5.0.0.1'
-# Use sqlite3 as the database for Active Record
-gem 'sqlite3'
+gem 'pg'
# Use Puma as the app server
gem 'puma', '~> 3.0'
# Use SCSS for stylesheets
@@ -15,7 +14,7 @@ gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.2'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
-# Bulma CSS
+gem 'haml'
gem "bulma-rails", "~> 0.2.3"
# Use jquery as the JavaScript library
gem 'jquery-rails'
diff --git a/Gemfile.lock b/Gemfile.lock
index da9c73e..c23f570 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -57,6 +57,8 @@ GEM
ffi (1.9.14)
globalid (0.3.7)
activesupport (>= 4.1.0)
+ haml (4.0.7)
+ tilt
i18n (0.7.0)
jbuilder (2.6.0)
activesupport (>= 3.0.0, < 5.1)
@@ -82,6 +84,7 @@ GEM
nio4r (1.2.1)
nokogiri (1.6.8.1)
mini_portile2 (~> 2.1.0)
+ pg (0.19.0)
puma (3.6.0)
rack (2.0.1)
rack-test (0.6.3)
@@ -132,7 +135,6 @@ GEM
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
- sqlite3 (1.3.12)
thor (0.19.1)
thread_safe (0.3.5)
tilt (2.0.5)
@@ -159,19 +161,20 @@ DEPENDENCIES
bulma-rails (~> 0.2.3)
byebug
coffee-rails (~> 4.2)
+ haml
jbuilder (~> 2.5)
jquery-rails
listen (~> 3.0.5)
+ pg
puma (~> 3.0)
rails (~> 5.0.0, >= 5.0.0.1)
sass-rails (~> 5.0)
spring
spring-watcher-listen (~> 2.0.0)
- sqlite3
turbolinks (~> 5)
tzinfo-data
uglifier (>= 1.3.0)
web-console
BUNDLED WITH
- 1.12.5
+ 1.13.6
diff --git a/app/assets/images/favicon.png b/app/assets/images/favicon.png
new file mode 100644
index 0000000..8e248bf
Binary files /dev/null and b/app/assets/images/favicon.png differ
diff --git a/app/assets/javascripts/todos.coffee b/app/assets/javascripts/todos.coffee
new file mode 100644
index 0000000..24f83d1
--- /dev/null
+++ b/app/assets/javascripts/todos.coffee
@@ -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/
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.scss
similarity index 73%
rename from app/assets/stylesheets/application.css
rename to app/assets/stylesheets/application.scss
index 0ebd7fe..81bd2b2 100644
--- a/app/assets/stylesheets/application.css
+++ b/app/assets/stylesheets/application.scss
@@ -13,3 +13,28 @@
*= require_tree .
*= require_self
*/
+@import "bulma";
+
+.hero {
+ margin-bottom: 30px;
+}
+
+.todo-list {
+ padding: 30px;
+}
+
+.addTodo {
+ margin-top: 30px;
+}
+
+.addTodo input {
+ width: 100%;
+ height: 50px;
+ padding: 10px;
+ resize: vertical;
+ font-size: 18px;
+}
+
+.addTodo label {
+ display: none;
+}
diff --git a/app/assets/stylesheets/scaffolds.scss b/app/assets/stylesheets/scaffolds.scss
new file mode 100644
index 0000000..443728e
--- /dev/null
+++ b/app/assets/stylesheets/scaffolds.scss
@@ -0,0 +1,34 @@
+#notice {
+ color: red;
+}
+
+.field_with_errors {
+ padding: 2px;
+ background-color: red;
+ display: table;
+}
+
+#error_explanation {
+ width: 450px;
+ border: 2px solid red;
+ padding: 7px;
+ padding-bottom: 0;
+ margin-bottom: 20px;
+ background-color: #f0f0f0;
+
+ h2 {
+ text-align: left;
+ font-weight: bold;
+ padding: 5px 5px 5px 15px;
+ font-size: 12px;
+ margin: -7px;
+ margin-bottom: 0;
+ background-color: #c00;
+ color: #fff;
+ }
+
+ ul li {
+ font-size: 12px;
+ list-style: square;
+ }
+}
diff --git a/app/assets/stylesheets/todos.scss b/app/assets/stylesheets/todos.scss
new file mode 100644
index 0000000..e69de29
diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb
new file mode 100644
index 0000000..91f174f
--- /dev/null
+++ b/app/controllers/todos_controller.rb
@@ -0,0 +1,78 @@
+class TodosController < ApplicationController
+ before_action :set_todo, only: [:show, :edit, :update, :destroy]
+
+ # GET /todos
+ # GET /todos.json
+ def index
+ @todos = Todo.all
+ @todo = Todo.new
+ end
+
+ # GET /todos/1
+ # GET /todos/1.json
+ def show
+ end
+
+ # GET /todos/new
+ def new
+ @todo = Todo.new
+ end
+
+ # GET /todos/1/edit
+ def edit
+ end
+
+ # POST /todos
+ # POST /todos.json
+ def create
+ @todo = Todo.new(todo_params)
+
+ respond_to do |format|
+ if @todo.content == ""
+ format.html { redirect_to todos_path, notice: 'Todo was blank!'}
+ format.json { render json: { error: 'Blank Todo!' }, status: :unprocessable_entity }
+ elsif @todo.save
+ format.html { redirect_to todos_path }
+ format.json { render :show, status: :created, location: @todo }
+ else
+ format.html { render todos_path }
+ format.json { render json: @todo.errors, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ # PATCH/PUT /todos/1
+ # PATCH/PUT /todos/1.json
+ def update
+ respond_to do |format|
+ if @todo.update(todo_params)
+ format.html { redirect_to todos_path }
+ format.json { render :show, status: :ok, location: @todo }
+ else
+ format.html { render :edit }
+ format.json { render json: @todo.errors, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ # DELETE /todos/1
+ # DELETE /todos/1.json
+ def destroy
+ @todo.destroy
+ respond_to do |format|
+ format.html { redirect_to todos_url, notice: 'Todo was successfully destroyed.' }
+ format.json { head :no_content }
+ end
+ end
+
+ private
+ # Use callbacks to share common setup or constraints between actions.
+ def set_todo
+ @todo = Todo.find(params[:id])
+ end
+
+ # Never trust parameters from the scary internet, only allow the white list through.
+ def todo_params
+ params.require(:todo).permit(:content)
+ end
+end
diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb
new file mode 100644
index 0000000..65ab195
--- /dev/null
+++ b/app/helpers/todos_helper.rb
@@ -0,0 +1,2 @@
+module TodosHelper
+end
diff --git a/app/models/todo.rb b/app/models/todo.rb
new file mode 100644
index 0000000..e7adee6
--- /dev/null
+++ b/app/models/todo.rb
@@ -0,0 +1,2 @@
+class Todo < ApplicationRecord
+end
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
deleted file mode 100644
index 0e51ed4..0000000
--- a/app/views/layouts/application.html.erb
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
- RailsStarter
- <%= csrf_meta_tags %>
-
- <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
- <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
-
-
-
- <%= yield %>
-
-
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
new file mode 100644
index 0000000..f805997
--- /dev/null
+++ b/app/views/layouts/application.html.haml
@@ -0,0 +1,15 @@
+!!!
+%html
+ %head
+ %title ToDo List
+ = favicon_link_tag "favicon.png", rel: 'shortcut icon', type: 'image/png'
+ = stylesheet_link_tag "application", media: "all"
+ = javascript_include_tag "application"
+ = csrf_meta_tags
+ %body
+ %section.hero.is-dark
+ .hero-body
+ .container
+ %h1.title Todo List
+ %h2.subtitle Submit a new Todo to get started!
+ = yield
diff --git a/app/views/todos/_form.html.erb b/app/views/todos/_form.html.erb
new file mode 100644
index 0000000..5378b98
--- /dev/null
+++ b/app/views/todos/_form.html.erb
@@ -0,0 +1,16 @@
+<%= form_for(todo, :html => {:class => 'addTodo'}) do |f| %>
+ <% if todo.errors.any? %>
+
+
<%= pluralize(todo.errors.count, "error") %> prohibited this todo from being saved:
+
+
+ <% todo.errors.full_messages.each do |message| %>
+ - <%= message %>
+ <% end %>
+
+
+ <% end %>
+
+ <%= f.text_field :content, autofocus: true, placeholder: 'Add a Todo!' %>
+ <%= f.submit 'Submit', :class => 'button is-dark is-fullwidth' %>
+<% end %>
diff --git a/app/views/todos/_todo.json.jbuilder b/app/views/todos/_todo.json.jbuilder
new file mode 100644
index 0000000..41019dd
--- /dev/null
+++ b/app/views/todos/_todo.json.jbuilder
@@ -0,0 +1,2 @@
+json.extract! todo, :id, :title, :description, :created_at, :updated_at
+json.url todo_url(todo, format: :json)
\ No newline at end of file
diff --git a/app/views/todos/edit.html.erb b/app/views/todos/edit.html.erb
new file mode 100644
index 0000000..97f0ce9
--- /dev/null
+++ b/app/views/todos/edit.html.erb
@@ -0,0 +1,6 @@
+Editing Todo
+
+<%= render 'form', todo: @todo %>
+
+<%= link_to 'Show', @todo %> |
+<%= link_to 'Back', todos_path %>
diff --git a/app/views/todos/index.html.haml b/app/views/todos/index.html.haml
new file mode 100644
index 0000000..fe39347
--- /dev/null
+++ b/app/views/todos/index.html.haml
@@ -0,0 +1,13 @@
+.container.todo-list
+ - if @todos.empty?
+ %p There are no todos!
+ - else
+ - @todos.each do |todo|
+ %article.media
+ .media-content
+ .content
+ %p= todo.content
+ .media-right
+ %a= link_to 'Delete', todo, method: :delete, class: 'button is-danger'
+ =render 'form', todo: @todo
+ %p#notice= notice
diff --git a/app/views/todos/index.json.jbuilder b/app/views/todos/index.json.jbuilder
new file mode 100644
index 0000000..83ef1b0
--- /dev/null
+++ b/app/views/todos/index.json.jbuilder
@@ -0,0 +1 @@
+json.array! @todos, partial: 'todos/todo', as: :todo
\ No newline at end of file
diff --git a/app/views/todos/show.html.haml b/app/views/todos/show.html.haml
new file mode 100644
index 0000000..e22fbbb
--- /dev/null
+++ b/app/views/todos/show.html.haml
@@ -0,0 +1,7 @@
+.container
+ %p#notice= notice
+ %br
+ .box
+ %p= @todo.content
+ = link_to 'Edit', edit_todo_path(@todo), class: 'button'
+ = link_to 'Back', todos_path, class: 'button'
diff --git a/app/views/todos/show.json.jbuilder b/app/views/todos/show.json.jbuilder
new file mode 100644
index 0000000..ddfec4b
--- /dev/null
+++ b/app/views/todos/show.json.jbuilder
@@ -0,0 +1 @@
+json.partial! "todos/todo", todo: @todo
\ No newline at end of file
diff --git a/config/database.yml b/config/database.yml
index 1c1a37c..b96c8ba 100644
--- a/config/database.yml
+++ b/config/database.yml
@@ -1,25 +1,12 @@
-# SQLite version 3.x
-# gem install sqlite3
-#
-# Ensure the SQLite 3 gem is defined in your Gemfile
-# gem 'sqlite3'
-#
-default: &default
- adapter: sqlite3
+development: &default
+ adapter: postgresql
+ encoding: unicode
+ database: postgres
pool: 5
- timeout: 5000
+ username: postgres
+ password:
+ host: db
-development:
- <<: *default
- database: db/development.sqlite3
-
-# Warning: The database defined as "test" will be erased and
-# re-generated from your development database when you run "rake".
-# Do not set this db to the same as development or production.
test:
<<: *default
- database: db/test.sqlite3
-
-production:
- <<: *default
- database: db/production.sqlite3
+ database: myapp_test
diff --git a/config/routes.rb b/config/routes.rb
index 787824f..54274a5 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,3 +1,5 @@
Rails.application.routes.draw do
+ root to: "todos#index"
+ resources :todos
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
diff --git a/db/migrate/20161119011946_create_tasks.rb b/db/migrate/20161119011946_create_tasks.rb
deleted file mode 100644
index 4e49038..0000000
--- a/db/migrate/20161119011946_create_tasks.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-class CreateTasks < ActiveRecord::Migration[5.0]
- def change
- create_table :tasks do |t|
- t.string :title
- t.text :note
- t.date :completed
-
- t.timestamps
- end
- end
-end
diff --git a/db/migrate/20161122050054_create_todos.rb b/db/migrate/20161122050054_create_todos.rb
new file mode 100644
index 0000000..616cad2
--- /dev/null
+++ b/db/migrate/20161122050054_create_todos.rb
@@ -0,0 +1,8 @@
+class CreateTodos < ActiveRecord::Migration[5.0]
+ def change
+ create_table :todos do |t|
+ t.string :content
+ t.timestamps
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 8a0ca3c..729ce8a 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,12 +10,13 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20161119011946) do
+ActiveRecord::Schema.define(version: 20161122050054) do
- create_table "tasks", force: :cascade do |t|
- t.string "title"
- t.text "note"
- t.date "completed"
+ # These are extensions that must be enabled in order to support this database
+ enable_extension "plpgsql"
+
+ create_table "todos", force: :cascade do |t|
+ t.string "content"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
diff --git a/db/seeds.rb b/db/seeds.rb
index 1beea2a..0afa7eb 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -5,3 +5,5 @@
#
# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
# Character.create(name: 'Luke', movie: movies.first)
+
+Todo.create(content: 'This is a sample todo.')
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..0d8ca90
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,12 @@
+version: '2'
+services:
+ db:
+ image: postgres
+ web:
+ build: .
+ volumes:
+ - .:/app
+ ports:
+ - "3000:3000"
+ depends_on:
+ - db
\ No newline at end of file
diff --git a/test/controllers/todos_controller_test.rb b/test/controllers/todos_controller_test.rb
new file mode 100644
index 0000000..720e84c
--- /dev/null
+++ b/test/controllers/todos_controller_test.rb
@@ -0,0 +1,48 @@
+require 'test_helper'
+
+class TodosControllerTest < ActionDispatch::IntegrationTest
+ setup do
+ @todo = todos(:one)
+ end
+
+ test "should get index" do
+ get todos_url
+ assert_response :success
+ end
+
+ test "should get new" do
+ get new_todo_url
+ assert_response :success
+ end
+
+ test "should create todo" do
+ assert_difference('Todo.count') do
+ post todos_url, params: { todo: { description: @todo.description, title: @todo.title } }
+ end
+
+ assert_redirected_to todo_url(Todo.last)
+ end
+
+ test "should show todo" do
+ get todo_url(@todo)
+ assert_response :success
+ end
+
+ test "should get edit" do
+ get edit_todo_url(@todo)
+ assert_response :success
+ end
+
+ test "should update todo" do
+ patch todo_url(@todo), params: { todo: { description: @todo.description, title: @todo.title } }
+ assert_redirected_to todo_url(@todo)
+ end
+
+ test "should destroy todo" do
+ assert_difference('Todo.count', -1) do
+ delete todo_url(@todo)
+ end
+
+ assert_redirected_to todos_url
+ end
+end
diff --git a/test/fixtures/todos.yml b/test/fixtures/todos.yml
new file mode 100644
index 0000000..97fbfc4
--- /dev/null
+++ b/test/fixtures/todos.yml
@@ -0,0 +1,9 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+ title: MyString
+ description: MyText
+
+two:
+ title: MyString
+ description: MyText
diff --git a/test/models/todo_test.rb b/test/models/todo_test.rb
new file mode 100644
index 0000000..243607e
--- /dev/null
+++ b/test/models/todo_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class TodoTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end