[from now] 2014/11/18 16:45:37

diff --git a/app/assets/javascripts/categories.js.coffee b/app/assets/javascripts/categories.js.coffee
new file mode 100644
index 0000000..24f83d1
--- /dev/null
+++ b/app/assets/javascripts/categories.js.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/categories.css.scss b/app/assets/stylesheets/categories.css.scss
new file mode 100644
index 0000000..ef1657f
--- /dev/null
+++ b/app/assets/stylesheets/categories.css.scss
@@ -0,0 +1,3 @@
+// Place all the styles related to the categories controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
diff --git a/app/assets/stylesheets/scaffolds.css.scss b/app/assets/stylesheets/scaffolds.css.scss
new file mode 100644
index 0000000..6ec6a8f
--- /dev/null
+++ b/app/assets/stylesheets/scaffolds.css.scss
@@ -0,0 +1,69 @@
+body {
+  background-color: #fff;
+  color: #333;
+  font-family: verdana, arial, helvetica, sans-serif;
+  font-size: 13px;
+  line-height: 18px;
+}
+
+p, ol, ul, td {
+  font-family: verdana, arial, helvetica, sans-serif;
+  font-size: 13px;
+  line-height: 18px;
+}
+
+pre {
+  background-color: #eee;
+  padding: 10px;
+  font-size: 11px;
+}
+
+a {
+  color: #000;
+  &:visited {
+    color: #666;
+  }
+  &:hover {
+    color: #fff;
+    background-color: #000;
+  }
+}
+
+div {
+  &.field, &.actions {
+    margin-bottom: 10px;
+  }
+}
+
+#notice {
+  color: green;
+}
+
+.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: 0px;
+    background-color: #c00;
+    color: #fff;
+  }
+  ul li {
+    font-size: 12px;
+    list-style: square;
+  }
+}
diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb
new file mode 100644
index 0000000..3a6b988
--- /dev/null
+++ b/app/controllers/categories_controller.rb
@@ -0,0 +1,47 @@
+class CategoriesController < ApplicationController
+  before_action :set_category, only: [:show, :edit, :update, :destroy]
+
+  respond_to :html
+
+  def index
+    @categories = Category.all
+    respond_with(@categories)
+  end
+
+  def show
+    respond_with(@category)
+  end
+
+  def new
+    @category = Category.new
+    respond_with(@category)
+  end
+
+  def edit
+  end
+
+  def create
+    @category = Category.new(category_params)
+    @category.save
+    respond_with(@category)
+  end
+
+  def update
+    @category.update(category_params)
+    respond_with(@category)
+  end
+
+  def destroy
+    @category.destroy
+    respond_with(@category)
+  end
+
+  private
+    def set_category
+      @category = Category.find(params[:id])
+    end
+
+    def category_params
+      params.require(:category).permit(:name, :user_id, :misc)
+    end
+end
diff --git a/app/helpers/categories_helper.rb b/app/helpers/categories_helper.rb
new file mode 100644
index 0000000..e06f315
--- /dev/null
+++ b/app/helpers/categories_helper.rb
@@ -0,0 +1,2 @@
+module CategoriesHelper
+end
diff --git a/app/models/category.rb b/app/models/category.rb
new file mode 100644
index 0000000..bbb6903
--- /dev/null
+++ b/app/models/category.rb
@@ -0,0 +1,3 @@
+class Category < ActiveRecord::Base
+  belongs_to :user
+end
diff --git a/app/views/categories/_form.html.erb b/app/views/categories/_form.html.erb
new file mode 100644
index 0000000..9596b00
--- /dev/null
+++ b/app/views/categories/_form.html.erb
@@ -0,0 +1,29 @@
+<%= form_for(@category) do |f| %>
+  <% if @category.errors.any? %>
+    <div id="error_explanation">
+      <h2><%= pluralize(@category.errors.count, "error") %> prohibited this category from being saved:</h2>
+
+      <ul>
+      <% @category.errors.full_messages.each do |message| %>
+        <li><%= message %></li>
+      <% end %>
+      </ul>
+    </div>
+  <% end %>
+
+  <div class="field">
+    <%= f.label :name %><br>
+    <%= f.text_field :name %>
+  </div>
+  <div class="field">
+    <%= f.label :user_id %><br>
+    <%= f.text_field :user_id %>
+  </div>
+  <div class="field">
+    <%= f.label :misc %><br>
+    <%= f.text_area :misc %>
+  </div>
+  <div class="actions">
+    <%= f.submit %>
+  </div>
+<% end %>
diff --git a/app/views/categories/edit.html.erb b/app/views/categories/edit.html.erb
new file mode 100644
index 0000000..fce22f7
--- /dev/null
+++ b/app/views/categories/edit.html.erb
@@ -0,0 +1,6 @@
+<h1>Editing category</h1>
+
+<%= render 'form' %>
+
+<%= link_to 'Show', @category %> |
+<%= link_to 'Back', categories_path %>
diff --git a/app/views/categories/index.html.erb b/app/views/categories/index.html.erb
new file mode 100644
index 0000000..a182d39
--- /dev/null
+++ b/app/views/categories/index.html.erb
@@ -0,0 +1,29 @@
+<h1>Listing categories</h1>
+
+<table>
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>User</th>
+      <th>Misc</th>
+      <th colspan="3"></th>
+    </tr>
+  </thead>
+
+  <tbody>
+    <% @categories.each do |category| %>
+      <tr>
+        <td><%= category.name %></td>
+        <td><%= category.user %></td>
+        <td><%= category.misc %></td>
+        <td><%= link_to 'Show', category %></td>
+        <td><%= link_to 'Edit', edit_category_path(category) %></td>
+        <td><%= link_to 'Destroy', category, method: :delete, data: { confirm: 'Are you sure?' } %></td>
+      </tr>
+    <% end %>
+  </tbody>
+</table>
+
+<br>
+
+<%= link_to 'New Category', new_category_path %>
diff --git a/app/views/categories/index.json.jbuilder b/app/views/categories/index.json.jbuilder
new file mode 100644
index 0000000..badd4c6
--- /dev/null
+++ b/app/views/categories/index.json.jbuilder
@@ -0,0 +1,4 @@
+json.array!(@categories) do |category|
+  json.extract! category, :id, :name, :user_id, :misc
+  json.url category_url(category, format: :json)
+end
diff --git a/app/views/categories/new.html.erb b/app/views/categories/new.html.erb
new file mode 100644
index 0000000..a84b5d3
--- /dev/null
+++ b/app/views/categories/new.html.erb
@@ -0,0 +1,5 @@
+<h1>New category</h1>
+
+<%= render 'form' %>
+
+<%= link_to 'Back', categories_path %>
diff --git a/app/views/categories/show.html.erb b/app/views/categories/show.html.erb
new file mode 100644
index 0000000..09aa2f5
--- /dev/null
+++ b/app/views/categories/show.html.erb
@@ -0,0 +1,19 @@
+<p id="notice"><%= notice %></p>
+
+<p>
+  <strong>Name:</strong>
+  <%= @category.name %>
+</p>
+
+<p>
+  <strong>User:</strong>
+  <%= @category.user %>
+</p>
+
+<p>
+  <strong>Misc:</strong>
+  <%= @category.misc %>
+</p>
+
+<%= link_to 'Edit', edit_category_path(@category) %> |
+<%= link_to 'Back', categories_path %>
diff --git a/app/views/categories/show.json.jbuilder b/app/views/categories/show.json.jbuilder
new file mode 100644
index 0000000..8a9bd18
--- /dev/null
+++ b/app/views/categories/show.json.jbuilder
@@ -0,0 +1 @@
+json.extract! @category, :id, :name, :user_id, :misc, :created_at, :updated_at
diff --git a/db/migrate/20141118070922_create_categories.rb b/db/migrate/20141118070922_create_categories.rb
new file mode 100644
index 0000000..2541d9e
--- /dev/null
+++ b/db/migrate/20141118070922_create_categories.rb
@@ -0,0 +1,11 @@
+class CreateCategories < ActiveRecord::Migration
+  def change
+    create_table :categories do |t|
+      t.string :name
+      t.references :user, index: true
+      t.text :misc
+
+      t.timestamps
+    end
+  end
+end
diff --git a/spec/controllers/categories_controller_spec.rb b/spec/controllers/categories_controller_spec.rb
new file mode 100644
index 0000000..ea159db
--- /dev/null
+++ b/spec/controllers/categories_controller_spec.rb
@@ -0,0 +1,159 @@
+require 'rails_helper'
+
+# This spec was generated by rspec-rails when you ran the scaffold generator.
+# It demonstrates how one might use RSpec to specify the controller code that
+# was generated by Rails when you ran the scaffold generator.
+#
+# It assumes that the implementation code is generated by the rails scaffold
+# generator.  If you are using any extension libraries to generate different
+# controller code, this generated spec may or may not pass.
+#
+# It only uses APIs available in rails and/or rspec-rails.  There are a number
+# of tools you can use to make these specs even more expressive, but we're
+# sticking to rails and rspec-rails APIs to keep things simple and stable.
+#
+# Compared to earlier versions of this generator, there is very limited use of
+# stubs and message expectations in this spec.  Stubs are only used when there
+# is no simpler way to get a handle on the object needed for the example.
+# Message expectations are only used when there is no simpler way to specify
+# that an instance is receiving a specific message.
+
+RSpec.describe CategoriesController, :type => :controller do
+
+  # This should return the minimal set of attributes required to create a valid
+  # Category. As you add validations to Category, be sure to
+  # adjust the attributes here as well.
+  let(:valid_attributes) {
+    skip("Add a hash of attributes valid for your model")
+  }
+
+  let(:invalid_attributes) {
+    skip("Add a hash of attributes invalid for your model")
+  }
+
+  # This should return the minimal set of values that should be in the session
+  # in order to pass any filters (e.g. authentication) defined in
+  # CategoriesController. Be sure to keep this updated too.
+  let(:valid_session) { {} }
+
+  describe "GET index" do
+    it "assigns all categories as @categories" do
+      category = Category.create! valid_attributes
+      get :index, {}, valid_session
+      expect(assigns(:categories)).to eq([category])
+    end
+  end
+
+  describe "GET show" do
+    it "assigns the requested category as @category" do
+      category = Category.create! valid_attributes
+      get :show, {:id => category.to_param}, valid_session
+      expect(assigns(:category)).to eq(category)
+    end
+  end
+
+  describe "GET new" do
+    it "assigns a new category as @category" do
+      get :new, {}, valid_session
+      expect(assigns(:category)).to be_a_new(Category)
+    end
+  end
+
+  describe "GET edit" do
+    it "assigns the requested category as @category" do
+      category = Category.create! valid_attributes
+      get :edit, {:id => category.to_param}, valid_session
+      expect(assigns(:category)).to eq(category)
+    end
+  end
+
+  describe "POST create" do
+    describe "with valid params" do
+      it "creates a new Category" do
+        expect {
+          post :create, {:category => valid_attributes}, valid_session
+        }.to change(Category, :count).by(1)
+      end
+
+      it "assigns a newly created category as @category" do
+        post :create, {:category => valid_attributes}, valid_session
+        expect(assigns(:category)).to be_a(Category)
+        expect(assigns(:category)).to be_persisted
+      end
+
+      it "redirects to the created category" do
+        post :create, {:category => valid_attributes}, valid_session
+        expect(response).to redirect_to(Category.last)
+      end
+    end
+
+    describe "with invalid params" do
+      it "assigns a newly created but unsaved category as @category" do
+        post :create, {:category => invalid_attributes}, valid_session
+        expect(assigns(:category)).to be_a_new(Category)
+      end
+
+      it "re-renders the 'new' template" do
+        post :create, {:category => invalid_attributes}, valid_session
+        expect(response).to render_template("new")
+      end
+    end
+  end
+
+  describe "PUT update" do
+    describe "with valid params" do
+      let(:new_attributes) {
+        skip("Add a hash of attributes valid for your model")
+      }
+
+      it "updates the requested category" do
+        category = Category.create! valid_attributes
+        put :update, {:id => category.to_param, :category => new_attributes}, valid_session
+        category.reload
+        skip("Add assertions for updated state")
+      end
+
+      it "assigns the requested category as @category" do
+        category = Category.create! valid_attributes
+        put :update, {:id => category.to_param, :category => valid_attributes}, valid_session
+        expect(assigns(:category)).to eq(category)
+      end
+
+      it "redirects to the category" do
+        category = Category.create! valid_attributes
+        put :update, {:id => category.to_param, :category => valid_attributes}, valid_session
+        expect(response).to redirect_to(category)
+      end
+    end
+
+    describe "with invalid params" do
+      it "assigns the category as @category" do
+        category = Category.create! valid_attributes
+        put :update, {:id => category.to_param, :category => invalid_attributes}, valid_session
+        expect(assigns(:category)).to eq(category)
+      end
+
+      it "re-renders the 'edit' template" do
+        category = Category.create! valid_attributes
+        put :update, {:id => category.to_param, :category => invalid_attributes}, valid_session
+        expect(response).to render_template("edit")
+      end
+    end
+  end
+
+  describe "DELETE destroy" do
+    it "destroys the requested category" do
+      category = Category.create! valid_attributes
+      expect {
+        delete :destroy, {:id => category.to_param}, valid_session
+      }.to change(Category, :count).by(-1)
+    end
+
+    it "redirects to the categories list" do
+      category = Category.create! valid_attributes
+      delete :destroy, {:id => category.to_param}, valid_session
+      expect(response).to redirect_to(categories_url)
+    end
+  end
+
+end
diff --git a/spec/helpers/categories_helper_spec.rb b/spec/helpers/categories_helper_spec.rb
new file mode 100644
index 0000000..83bffcd
--- /dev/null
+++ b/spec/helpers/categories_helper_spec.rb
@@ -0,0 +1,15 @@
+require 'rails_helper'
+
+# Specs in this file have access to a helper object that includes
+# the CategoriesHelper. For example:
+#
+# describe CategoriesHelper do
+#   describe "string concat" do
+#     it "concats two strings with spaces" do
+#       expect(helper.concat_strings("this","that")).to eq("this that")
+#     end
+#   end
+# end
+RSpec.describe CategoriesHelper, :type => :helper do
+  pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/models/category_spec.rb b/spec/models/category_spec.rb
new file mode 100644
index 0000000..880d824
--- /dev/null
+++ b/spec/models/category_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe Category, :type => :model do
+  pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/requests/categories_spec.rb b/spec/requests/categories_spec.rb
new file mode 100644
index 0000000..5a82e34
--- /dev/null
+++ b/spec/requests/categories_spec.rb
@@ -0,0 +1,10 @@
+require 'rails_helper'
+
+RSpec.describe "Categories", :type => :request do
+  describe "GET /categories" do
+    it "works! (now write some real specs)" do
+      get categories_path
+      expect(response).to have_http_status(200)
+    end
+  end
+end
diff --git a/spec/routing/categories_routing_spec.rb b/spec/routing/categories_routing_spec.rb
new file mode 100644
index 0000000..3924885
--- /dev/null
+++ b/spec/routing/categories_routing_spec.rb
@@ -0,0 +1,35 @@
+require "rails_helper"
+
+RSpec.describe CategoriesController, :type => :routing do
+  describe "routing" do
+
+    it "routes to #index" do
+      expect(:get => "/categories").to route_to("categories#index")
+    end
+
+    it "routes to #new" do
+      expect(:get => "/categories/new").to route_to("categories#new")
+    end
+
+    it "routes to #show" do
+      expect(:get => "/categories/1").to route_to("categories#show", :id => "1")
+    end
+
+    it "routes to #edit" do
+      expect(:get => "/categories/1/edit").to route_to("categories#edit", :id => "1")
+    end
+
+    it "routes to #create" do
+      expect(:post => "/categories").to route_to("categories#create")
+    end
+
+    it "routes to #update" do
+      expect(:put => "/categories/1").to route_to("categories#update", :id => "1")
+    end
+
+    it "routes to #destroy" do
+      expect(:delete => "/categories/1").to route_to("categories#destroy", :id => "1")
+    end
+
+  end
+end
diff --git a/spec/views/categories/edit.html.erb_spec.rb b/spec/views/categories/edit.html.erb_spec.rb
new file mode 100644
index 0000000..46440bc
--- /dev/null
+++ b/spec/views/categories/edit.html.erb_spec.rb
@@ -0,0 +1,24 @@
+require 'rails_helper'
+
+RSpec.describe "categories/edit", :type => :view do
+  before(:each) do
+    @category = assign(:category, Category.create!(
+      :name => "MyString",
+      :user => nil,
+      :misc => "MyText"
+    ))
+  end
+
+  it "renders the edit category form" do
+    render
+
+    assert_select "form[action=?][method=?]", category_path(@category), "post" do
+
+      assert_select "input#category_name[name=?]", "category[name]"
+
+      assert_select "input#category_user_id[name=?]", "category[user_id]"
+
+      assert_select "textarea#category_misc[name=?]", "category[misc]"
+    end
+  end
+end
diff --git a/spec/views/categories/index.html.erb_spec.rb b/spec/views/categories/index.html.erb_spec.rb
new file mode 100644
index 0000000..180085d
--- /dev/null
+++ b/spec/views/categories/index.html.erb_spec.rb
@@ -0,0 +1,25 @@
+require 'rails_helper'
+
+RSpec.describe "categories/index", :type => :view do
+  before(:each) do
+    assign(:categories, [
+      Category.create!(
+        :name => "Name",
+        :user => nil,
+        :misc => "MyText"
+      ),
+      Category.create!(
+        :name => "Name",
+        :user => nil,
+        :misc => "MyText"
+      )
+    ])
+  end
+
+  it "renders a list of categories" do
+    render
+    assert_select "tr>td", :text => "Name".to_s, :count => 2
+    assert_select "tr>td", :text => nil.to_s, :count => 2
+    assert_select "tr>td", :text => "MyText".to_s, :count => 2
+  end
+end
diff --git a/spec/views/categories/new.html.erb_spec.rb b/spec/views/categories/new.html.erb_spec.rb
new file mode 100644
index 0000000..cbf1018
--- /dev/null
+++ b/spec/views/categories/new.html.erb_spec.rb
@@ -0,0 +1,24 @@
+require 'rails_helper'
+
+RSpec.describe "categories/new", :type => :view do
+  before(:each) do
+    assign(:category, Category.new(
+      :name => "MyString",
+      :user => nil,
+      :misc => "MyText"
+    ))
+  end
+
+  it "renders new category form" do
+    render
+
+    assert_select "form[action=?][method=?]", categories_path, "post" do
+
+      assert_select "input#category_name[name=?]", "category[name]"
+
+      assert_select "input#category_user_id[name=?]", "category[user_id]"
+
+      assert_select "textarea#category_misc[name=?]", "category[misc]"
+    end
+  end
+end
diff --git a/spec/views/categories/show.html.erb_spec.rb b/spec/views/categories/show.html.erb_spec.rb
new file mode 100644
index 0000000..1b6a736
--- /dev/null
+++ b/spec/views/categories/show.html.erb_spec.rb
@@ -0,0 +1,18 @@
+require 'rails_helper'
+
+RSpec.describe "categories/show", :type => :view do
+  before(:each) do
+    @category = assign(:category, Category.create!(
+      :name => "Name",
+      :user => nil,
+      :misc => "MyText"
+    ))
+  end
+
+  it "renders attributes in <p>" do
+    render
+    expect(rendered).to match(/Name/)
+    expect(rendered).to match(//)
+    expect(rendered).to match(/MyText/)
+  end
+end