diff --git a/.idea/.generators b/.idea/.generators
new file mode 100644
index 0000000..1618976
--- /dev/null
+++ b/.idea/.generators
@@ -0,0 +1,8 @@
+
+
diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks
new file mode 100644
index 0000000..7b36787
--- /dev/null
+++ b/.idea/.rakeTasks
@@ -0,0 +1,7 @@
+
+
diff --git a/.idea/DocStore.iml b/.idea/DocStore.iml
new file mode 100644
index 0000000..085c46a
--- /dev/null
+++ b/.idea/DocStore.iml
@@ -0,0 +1,196 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..cb3adc9
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..05f8f4f
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/Development__DocStore.xml b/.idea/runConfigurations/Development__DocStore.xml
new file mode 100644
index 0000000..8975ef2
--- /dev/null
+++ b/.idea/runConfigurations/Development__DocStore.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/Production__DocStore.xml b/.idea/runConfigurations/Production__DocStore.xml
new file mode 100644
index 0000000..eb0c09b
--- /dev/null
+++ b/.idea/runConfigurations/Production__DocStore.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/spec__DocStore.xml b/.idea/runConfigurations/spec__DocStore.xml
new file mode 100644
index 0000000..54ec51c
--- /dev/null
+++ b/.idea/runConfigurations/spec__DocStore.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/test__DocStore.xml b/.idea/runConfigurations/test__DocStore.xml
new file mode 100644
index 0000000..25022cc
--- /dev/null
+++ b/.idea/runConfigurations/test__DocStore.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..888ba5e
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,394 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ DEFINITION_ORDER
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ project
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1480016844651
+
+
+ 1480016844651
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ file://$PROJECT_DIR$/app/controllers/categories_controller.rb
+ 27
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/assets/javascripts/categories.coffee b/app/assets/javascripts/categories.coffee
new file mode 100644
index 0000000..24f83d1
--- /dev/null
+++ b/app/assets/javascripts/categories.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.scss b/app/assets/stylesheets/application.scss
index 1d43d32..2a2a97b 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -14,6 +14,8 @@
*= require_self
*/
+ body, body > p, body > ol, body > ul, body > td { margin: 8px !important }
+
#columns {
display: flex;
@@ -24,6 +26,18 @@
#side {
padding: 1em 2em;
+
+ ul {
+ padding: 0;
+
+ li {
+ list-style: none;
+
+ a {
+ font-size: small;
+ }
+ }
+ }
}
}
diff --git a/app/assets/stylesheets/categories.scss b/app/assets/stylesheets/categories.scss
new file mode 100644
index 0000000..42976cb
--- /dev/null
+++ b/app/assets/stylesheets/categories.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/controllers/categories_controller.rb b/app/controllers/categories_controller.rb
new file mode 100644
index 0000000..d128a54
--- /dev/null
+++ b/app/controllers/categories_controller.rb
@@ -0,0 +1,76 @@
+class CategoriesController < ApplicationController
+ before_action :set_category, only: [:show, :edit, :update, :destroy]
+
+ # GET /categories
+ # GET /categories.json
+ def index
+ @categories = Category.all
+ end
+
+ # GET /categories/1
+ # GET /categories/1.json
+ def show
+ end
+
+ # GET /categories/new
+ def new
+ @category = Category.new
+ @category.user = User.find(session[:user_id]) # TODO: fuer das setzen der moeglichen subcategories
+ end
+
+ # GET /categories/1/edit
+ def edit
+ end
+
+ # POST /categories
+ # POST /categories.json
+ def create
+ @category = Category.new(category_params)
+ @category.user = User.find(session[:user_id]) # TODO: wird ja beim setzen der subcategories nicht in das form geschrieben!
+
+ respond_to do |format|
+ if @category.save
+ format.html { redirect_to @category, notice: 'Category was successfully created.' }
+ format.json { render :show, status: :created, location: @category }
+ else
+ format.html { render :new }
+ format.json { render json: @category.errors, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ # PATCH/PUT /categories/1
+ # PATCH/PUT /categories/1.json
+ def update
+ respond_to do |format|
+ if @category.update(category_params)
+ format.html { redirect_to @category, notice: 'Category was successfully updated.' }
+ format.json { render :show, status: :ok, location: @category }
+ else
+ format.html { render :edit }
+ format.json { render json: @category.errors, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ # DELETE /categories/1
+ # DELETE /categories/1.json
+ def destroy
+ @category.destroy
+ respond_to do |format|
+ format.html { redirect_to categories_url, notice: 'Category was successfully destroyed.' }
+ format.json { head :no_content }
+ end
+ end
+
+ private
+ # Use callbacks to share common setup or constraints between actions.
+ def set_category
+ @category = Category.find(params[:id])
+ end
+
+ # Never trust parameters from the scary internet, only allow the white list through.
+ def category_params
+ params.require(:category).permit(:name, :parent_id)
+ end
+end
diff --git a/app/controllers/documents_controller.rb b/app/controllers/documents_controller.rb
index ee9616c..74f489f 100644
--- a/app/controllers/documents_controller.rb
+++ b/app/controllers/documents_controller.rb
@@ -75,6 +75,6 @@ class DocumentsController < ApplicationController
# Never trust parameters from the scary internet, only allow the white list through.
def document_params
- params.require(:document).permit(:doc)
+ params.require(:document).permit(:doc, :category_id)
end
end
diff --git a/app/helpers/categories_helper.rb b/app/helpers/categories_helper.rb
new file mode 100644
index 0000000..054d6f3
--- /dev/null
+++ b/app/helpers/categories_helper.rb
@@ -0,0 +1,20 @@
+module CategoriesHelper
+ def category_collection_select
+ cats = []
+ Category.where(user_id: @category.user_id).each do |cat|
+ s = cat.name
+ cat_parent = Category.find_by(id: cat.parent_id)
+
+ while cat_parent != nil do
+ s = cat_parent.name + "/" + s
+ cat_parent = Category.find_by(id: cat_parent.parent_id)
+ end
+
+ cat.name = s
+ cats.push cat
+ end
+ collection_select(:category, :parent_id, cats.sort_by(&:name), :id, :name, include_blank: true)
+ end
+
+
+end
diff --git a/app/models/category.rb b/app/models/category.rb
new file mode 100644
index 0000000..60ce423
--- /dev/null
+++ b/app/models/category.rb
@@ -0,0 +1,28 @@
+class Category < ApplicationRecord
+ has_many :documents
+ has_many :subcategories, class_name: 'Category', foreign_key: 'parent_id', dependent: :destroy
+ belongs_to :parent, class_name: 'Category', optional: true
+ belongs_to :user
+
+ before_destroy :check_for_subcategories
+
+ def get_fqcn
+ fqcn = name
+ cat_parent = parent
+
+ while cat_parent != nil do
+ fqcn = cat_parent.name + "/" + fqcn
+ cat_parent = cat_parent.parent
+ end
+
+ fqcn
+ end
+
+ private
+ def check_for_subcategories
+ unless subcategories.empty?
+ errors.add(:base, 'Subcategories present')
+ throw :abort
+ end
+ end
+end
diff --git a/app/models/document.rb b/app/models/document.rb
index 5a6a4f8..6408c51 100644
--- a/app/models/document.rb
+++ b/app/models/document.rb
@@ -1,5 +1,6 @@
class Document < ApplicationRecord
belongs_to :user
+ belongs_to :category
has_and_belongs_to_many :tags
has_attached_file :doc,
diff --git a/app/models/user.rb b/app/models/user.rb
index 26dfd33..e8412a4 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -2,4 +2,5 @@ class User < ApplicationRecord
has_secure_password
has_many :documents, dependent: :destroy
+ has_many :categories, dependent: :destroy
end
diff --git a/app/views/categories/_category.json.jbuilder b/app/views/categories/_category.json.jbuilder
new file mode 100644
index 0000000..702efe5
--- /dev/null
+++ b/app/views/categories/_category.json.jbuilder
@@ -0,0 +1,2 @@
+json.extract! category, :id, :name, :created_at, :updated_at
+json.url category_url(category, format: :json)
\ No newline at end of file
diff --git a/app/views/categories/_form.html.erb b/app/views/categories/_form.html.erb
new file mode 100644
index 0000000..881b3b6
--- /dev/null
+++ b/app/views/categories/_form.html.erb
@@ -0,0 +1,27 @@
+<%= form_for(category) do |f| %>
+ <% if category.errors.any? %>
+
+
<%= pluralize(category.errors.count, "error") %> prohibited this category from being saved:
+
+
+ <% category.errors.full_messages.each do |message| %>
+ - <%= message %>
+ <% end %>
+
+
+ <% end %>
+
+
+ <%= f.label :name %>
+ <%= f.text_field :name %>
+
+
+
+ <%= f.label :category %>
+ <%= category_collection_select %>
+
+
+
+ <%= f.submit %>
+
+<% end %>
diff --git a/app/views/categories/edit.html.erb b/app/views/categories/edit.html.erb
new file mode 100644
index 0000000..b969417
--- /dev/null
+++ b/app/views/categories/edit.html.erb
@@ -0,0 +1,6 @@
+Editing Category
+
+<%= render 'form', category: @category %>
+
+<%= 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..d28af96
--- /dev/null
+++ b/app/views/categories/index.html.erb
@@ -0,0 +1,27 @@
+<%= notice %>
+
+Categories
+
+
+
+
+ | Name |
+ |
+
+
+
+
+ <% @categories.order(:name).each do |category| %>
+
+ | <%= category.get_fqcn %> |
+ <%= link_to 'Show', category %> |
+ <%= link_to 'Edit', edit_category_path(category) %> |
+ <%= link_to 'Destroy', category, method: :delete, data: { confirm: 'Are you sure?' } %> |
+
+ <% end %>
+
+
+
+
+
+<%= 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..56ca9f3
--- /dev/null
+++ b/app/views/categories/index.json.jbuilder
@@ -0,0 +1 @@
+json.array! @categories, partial: 'categories/category', as: :category
\ No newline at end of file
diff --git a/app/views/categories/new.html.erb b/app/views/categories/new.html.erb
new file mode 100644
index 0000000..91d5ef7
--- /dev/null
+++ b/app/views/categories/new.html.erb
@@ -0,0 +1,5 @@
+New Category
+
+<%= render 'form', category: @category %>
+
+<%= 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..28c3c40
--- /dev/null
+++ b/app/views/categories/show.html.erb
@@ -0,0 +1,14 @@
+<%= notice %>
+
+
+ Name:
+ <%= @category.name %>
+
+
+
+ Full qualified category name:
+ <%= @category.get_fqcn %>
+
+
+<%= 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..80b819c
--- /dev/null
+++ b/app/views/categories/show.json.jbuilder
@@ -0,0 +1 @@
+json.partial! "categories/category", category: @category
\ No newline at end of file
diff --git a/app/views/documents/_form.html.erb b/app/views/documents/_form.html.erb
index 38a11c7..ead9cdb 100644
--- a/app/views/documents/_form.html.erb
+++ b/app/views/documents/_form.html.erb
@@ -16,6 +16,11 @@
<%= f.file_field :doc %>
+
+ <%= f.label :category %>
+ <%= f.collection_select(:category_id, Category.where(user_id: session[:user_id]).sort_by(&:get_fqcn), :id, :get_fqcn) %>
+
+
<%= f.submit %>
diff --git a/app/views/documents/show.html.erb b/app/views/documents/show.html.erb
index 2dc5a74..c34b53d 100644
--- a/app/views/documents/show.html.erb
+++ b/app/views/documents/show.html.erb
@@ -6,6 +6,11 @@
+ Category:
+ <%= @document.category.get_fqcn %>
+
+
+
<%= link_to @document.doc_file_name, @document.doc.url %>
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 56e9d7f..77cc36f 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -11,7 +11,25 @@
+
<% if session[:user_id] %>
+
+
<%= button_to 'Logout', logout_path, method: :delete %>
<% end %>
diff --git a/config/routes.rb b/config/routes.rb
index bdaa0df..810f3c1 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,14 +1,13 @@
Rails.application.routes.draw do
- resources :documents
+ root 'documents#index', as: 'documents_index'
- root 'users#index', as: 'users_index'
+ resources :categories
+ resources :documents
+ resources :users
controller :sessions do
get 'login' => :new
post 'login' => :create
delete 'logout' => :destroy
end
-
- resources :users
- # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
diff --git a/db/migrate/20161124182250_create_categories.rb b/db/migrate/20161124182250_create_categories.rb
new file mode 100644
index 0000000..e173243
--- /dev/null
+++ b/db/migrate/20161124182250_create_categories.rb
@@ -0,0 +1,10 @@
+class CreateCategories < ActiveRecord::Migration[5.0]
+ def change
+ create_table :categories do |t|
+ t.string :name
+ t.references :parent
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20161124182924_add_user_to_category.rb b/db/migrate/20161124182924_add_user_to_category.rb
new file mode 100644
index 0000000..3c0ba53
--- /dev/null
+++ b/db/migrate/20161124182924_add_user_to_category.rb
@@ -0,0 +1,5 @@
+class AddUserToCategory < ActiveRecord::Migration[5.0]
+ def change
+ add_reference :categories, :user, index: true
+ end
+end
diff --git a/db/migrate/20161124223446_add_category_to_document.rb b/db/migrate/20161124223446_add_category_to_document.rb
new file mode 100644
index 0000000..be09466
--- /dev/null
+++ b/db/migrate/20161124223446_add_category_to_document.rb
@@ -0,0 +1,5 @@
+class AddCategoryToDocument < ActiveRecord::Migration[5.0]
+ def change
+ add_reference :documents, :category, index: true
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 5536e32..54f52a8 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,17 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20161124174721) do
+ActiveRecord::Schema.define(version: 20161124223446) do
+
+ create_table "categories", force: :cascade do |t|
+ t.string "name"
+ t.integer "parent_id"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.integer "user_id"
+ t.index ["parent_id"], name: "index_categories_on_parent_id"
+ t.index ["user_id"], name: "index_categories_on_user_id"
+ end
create_table "documents", force: :cascade do |t|
t.string "name"
@@ -22,6 +32,8 @@ ActiveRecord::Schema.define(version: 20161124174721) do
t.datetime "doc_updated_at"
t.string "doc_fingerprint"
t.integer "user_id"
+ t.integer "category_id"
+ t.index ["category_id"], name: "index_documents_on_category_id"
t.index ["doc_fingerprint"], name: "index_documents_on_doc_fingerprint"
t.index ["user_id"], name: "index_documents_on_user_id"
end
diff --git a/test/controllers/categories_controller_test.rb b/test/controllers/categories_controller_test.rb
new file mode 100644
index 0000000..017eb06
--- /dev/null
+++ b/test/controllers/categories_controller_test.rb
@@ -0,0 +1,48 @@
+require 'test_helper'
+
+class CategoriesControllerTest < ActionDispatch::IntegrationTest
+ setup do
+ @category = categories(:one)
+ end
+
+ test "should get index" do
+ get categories_url
+ assert_response :success
+ end
+
+ test "should get new" do
+ get new_category_url
+ assert_response :success
+ end
+
+ test "should create category" do
+ assert_difference('Category.count') do
+ post categories_url, params: { category: { name: @category.name } }
+ end
+
+ assert_redirected_to category_url(Category.last)
+ end
+
+ test "should show category" do
+ get category_url(@category)
+ assert_response :success
+ end
+
+ test "should get edit" do
+ get edit_category_url(@category)
+ assert_response :success
+ end
+
+ test "should update category" do
+ patch category_url(@category), params: { category: { name: @category.name } }
+ assert_redirected_to category_url(@category)
+ end
+
+ test "should destroy category" do
+ assert_difference('Category.count', -1) do
+ delete category_url(@category)
+ end
+
+ assert_redirected_to categories_url
+ end
+end
diff --git a/test/fixtures/categories.yml b/test/fixtures/categories.yml
new file mode 100644
index 0000000..56066c6
--- /dev/null
+++ b/test/fixtures/categories.yml
@@ -0,0 +1,7 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+ name: MyString
+
+two:
+ name: MyString
diff --git a/test/models/category_test.rb b/test/models/category_test.rb
new file mode 100644
index 0000000..4733541
--- /dev/null
+++ b/test/models/category_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class CategoryTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end