From 8d2a466b1aa0d27847c5470daedc094246cab294 Mon Sep 17 00:00:00 2001 From: Nils Dittberner Date: Thu, 24 Nov 2016 23:55:58 +0100 Subject: [PATCH] It's possible to have categories. Yay! --- .idea/.generators | 8 + .idea/.rakeTasks | 7 + .idea/DocStore.iml | 196 ++++++++++ .idea/misc.xml | 14 + .idea/modules.xml | 8 + .idea/runConfigurations/Development__DocStore.xml | 27 ++ .idea/runConfigurations/Production__DocStore.xml | 27 ++ .idea/runConfigurations/spec__DocStore.xml | 25 ++ .idea/runConfigurations/test__DocStore.xml | 27 ++ .idea/vcs.xml | 6 + .idea/workspace.xml | 394 +++++++++++++++++++++ app/assets/javascripts/categories.coffee | 3 + app/assets/stylesheets/application.scss | 14 + app/assets/stylesheets/categories.scss | 3 + app/controllers/categories_controller.rb | 76 ++++ app/controllers/documents_controller.rb | 2 +- app/helpers/categories_helper.rb | 20 ++ app/models/category.rb | 28 ++ app/models/document.rb | 1 + app/models/user.rb | 1 + app/views/categories/_category.json.jbuilder | 2 + app/views/categories/_form.html.erb | 27 ++ app/views/categories/edit.html.erb | 6 + app/views/categories/index.html.erb | 27 ++ app/views/categories/index.json.jbuilder | 1 + app/views/categories/new.html.erb | 5 + app/views/categories/show.html.erb | 14 + app/views/categories/show.json.jbuilder | 1 + app/views/documents/_form.html.erb | 5 + app/views/documents/show.html.erb | 5 + app/views/layouts/application.html.erb | 18 + config/routes.rb | 9 +- db/migrate/20161124182250_create_categories.rb | 10 + db/migrate/20161124182924_add_user_to_category.rb | 5 + .../20161124223446_add_category_to_document.rb | 5 + db/schema.rb | 14 +- test/controllers/categories_controller_test.rb | 48 +++ test/fixtures/categories.yml | 7 + test/models/category_test.rb | 7 + 39 files changed, 1096 insertions(+), 7 deletions(-) create mode 100644 .idea/.generators create mode 100644 .idea/.rakeTasks create mode 100644 .idea/DocStore.iml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/runConfigurations/Development__DocStore.xml create mode 100644 .idea/runConfigurations/Production__DocStore.xml create mode 100644 .idea/runConfigurations/spec__DocStore.xml create mode 100644 .idea/runConfigurations/test__DocStore.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml create mode 100644 app/assets/javascripts/categories.coffee create mode 100644 app/assets/stylesheets/categories.scss create mode 100644 app/controllers/categories_controller.rb create mode 100644 app/helpers/categories_helper.rb create mode 100644 app/models/category.rb create mode 100644 app/views/categories/_category.json.jbuilder create mode 100644 app/views/categories/_form.html.erb create mode 100644 app/views/categories/edit.html.erb create mode 100644 app/views/categories/index.html.erb create mode 100644 app/views/categories/index.json.jbuilder create mode 100644 app/views/categories/new.html.erb create mode 100644 app/views/categories/show.html.erb create mode 100644 app/views/categories/show.json.jbuilder create mode 100644 db/migrate/20161124182250_create_categories.rb create mode 100644 db/migrate/20161124182924_add_user_to_category.rb create mode 100644 db/migrate/20161124223446_add_category_to_document.rb create mode 100644 test/controllers/categories_controller_test.rb create mode 100644 test/fixtures/categories.yml create mode 100644 test/models/category_test.rb 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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:

+ + +
+ <% 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

+ + + + + + + + + + + <% @categories.order(:name).each do |category| %> + + + + + + + <% end %> + +
Name
<%= 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?' } %>
+ +
+ +<%= 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