From c8732b6332579028a9c8b01ee5024b8f14105338 Mon Sep 17 00:00:00 2001 From: Roscoe Date: Wed, 10 Sep 2025 03:08:27 +0100 Subject: [PATCH] Tapes are now Clips, also they have categories --- .gitignore | 2 + app/controllers/categories_controller.rb | 49 +++++++++++++++++++ app/controllers/clips_controller.rb | 48 ++++++++++++++++++ app/controllers/home_controller.rb | 2 +- app/controllers/tapes_controller.rb | 48 ------------------ app/helpers/categories_helper.rb | 2 + app/helpers/clips_helper.rb | 9 ++++ app/helpers/tapes_helper.rb | 2 - app/models/category.rb | 3 ++ app/models/{tape.rb => clip.rb} | 3 +- app/views/categories/_form.html.erb | 10 ++++ app/views/categories/edit.html.erb | 4 ++ app/views/categories/index.html.erb | 9 ++++ app/views/categories/new.html.erb | 4 ++ app/views/categories/show.html.erb | 42 ++++++++++++++++ app/views/{tapes => clips}/_form.html.erb | 3 +- app/views/clips/edit.html.erb | 4 ++ app/views/clips/index.html.erb | 36 ++++++++++++++ app/views/clips/new.html.erb | 4 ++ app/views/clips/show.html.erb | 12 +++++ app/views/home/index.html.erb | 6 +-- app/views/layouts/application.html.erb | 9 +++- app/views/tapes/edit.html.erb | 4 -- app/views/tapes/index.html.erb | 28 ----------- app/views/tapes/new.html.erb | 4 -- app/views/tapes/show.html.erb | 11 ----- config/routes.rb | 3 +- db/migrate/20250907225919_create_tapes.rb | 9 ---- db/migrate/20250908185632_create_clips.rb | 11 +++++ .../20250909013509_create_categories.rb | 9 ++++ db/schema.rb | 23 ++++++--- .../controllers/categories_controller_test.rb | 7 +++ ...oller_test.rb => clips_controller_test.rb} | 2 +- test/fixtures/categories.yml | 7 +++ test/fixtures/clips.yml | 7 +++ test/models/category_test.rb | 7 +++ test/models/{tape_test.rb => clip_test.rb} | 2 +- 37 files changed, 322 insertions(+), 123 deletions(-) create mode 100644 app/controllers/categories_controller.rb create mode 100644 app/controllers/clips_controller.rb delete mode 100644 app/controllers/tapes_controller.rb create mode 100644 app/helpers/categories_helper.rb create mode 100644 app/helpers/clips_helper.rb delete mode 100644 app/helpers/tapes_helper.rb create mode 100644 app/models/category.rb rename app/models/{tape.rb => clip.rb} (54%) 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/new.html.erb create mode 100644 app/views/categories/show.html.erb rename app/views/{tapes => clips}/_form.html.erb (60%) create mode 100644 app/views/clips/edit.html.erb create mode 100644 app/views/clips/index.html.erb create mode 100644 app/views/clips/new.html.erb create mode 100644 app/views/clips/show.html.erb delete mode 100644 app/views/tapes/edit.html.erb delete mode 100644 app/views/tapes/index.html.erb delete mode 100644 app/views/tapes/new.html.erb delete mode 100644 app/views/tapes/show.html.erb delete mode 100644 db/migrate/20250907225919_create_tapes.rb create mode 100644 db/migrate/20250908185632_create_clips.rb create mode 100644 db/migrate/20250909013509_create_categories.rb create mode 100644 test/controllers/categories_controller_test.rb rename test/controllers/{tapes_controller_test.rb => clips_controller_test.rb} (56%) create mode 100644 test/fixtures/categories.yml create mode 100644 test/fixtures/clips.yml create mode 100644 test/models/category_test.rb rename test/models/{tape_test.rb => clip_test.rb} (65%) diff --git a/.gitignore b/.gitignore index f92525c..c0ef15b 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,5 @@ # Ignore master key for decrypting credentials and more. /config/master.key + +**/.DS_Store \ No newline at end of file diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb new file mode 100644 index 0000000..e84f58f --- /dev/null +++ b/app/controllers/categories_controller.rb @@ -0,0 +1,49 @@ +class CategoriesController < ApplicationController + allow_unauthenticated_access only: %i[ index show ] + before_action :set_category, only: %i[ show edit update destroy ] + def index + @categories = Category.all + end + + def show + @clips = Clip.where("category_id = ?", params[:id]) + end + + def new + @category = Category.new + end + + def create + @category = Category.new(category_params) + if @category.save + redirect_to @category + else + render :new, status: :unprocessable_entity + end + end + + def edit + end + + def update + if @category.update(category_params) + redirect_to @category + else + render :edit, status: :unprocessable_entity + end + end + + def destroy + @category.destroy + redirect_to categories_path + end + + private + def set_category + @category = Category.find(params[:id]) + end + + def category_params + params.expect(category: [ :name ]) + end +end diff --git a/app/controllers/clips_controller.rb b/app/controllers/clips_controller.rb new file mode 100644 index 0000000..6fceeff --- /dev/null +++ b/app/controllers/clips_controller.rb @@ -0,0 +1,48 @@ +class ClipsController < ApplicationController + allow_unauthenticated_access only: %i[ index show ] + before_action :set_clip, only: %i[ show edit update destroy ] + def index + @clips = Clip.all + end + + def show + end + + def new + @clip = Clip.new + end + + def create + @clip = Clip.new(clip_params) + if @clip.save + redirect_to @clip + else + render :new, status: :unprocessable_entity + end + end + + def edit + end + + def update + if @clip.update(clip_params) + redirect_to @clip + else + render :edit, status: :unprocessable_entity + end + end + + def destroy + @clip.destroy + redirect_to clips_path + end + + private + def set_clip + @clip = Clip.find(params[:id]) + end + + def clip_params + params.expect(clip: [ :title, :video, :category_id ]) + end +end diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb index 743238c..901e651 100644 --- a/app/controllers/home_controller.rb +++ b/app/controllers/home_controller.rb @@ -1,5 +1,5 @@ class HomeController < ApplicationController def index - @tapes = Tape.order("updated_at DESC").limit(10) + @clips = Clip.order("updated_at DESC").limit(10) end end diff --git a/app/controllers/tapes_controller.rb b/app/controllers/tapes_controller.rb deleted file mode 100644 index 102b95d..0000000 --- a/app/controllers/tapes_controller.rb +++ /dev/null @@ -1,48 +0,0 @@ -class TapesController < ApplicationController - allow_unauthenticated_access only: %i[ index show ] - before_action :set_tape, only: %i[ show edit update destroy ] - def index - @tapes = Tape.all - end - - def show - end - - def new - @tape = Tape.new - end - - def create - @tape = Tape.new(tape_params) - if @tape.save - redirect_to @tape - else - render :new, status: :unprocessable_entity - end - end - - def edit - end - - def update - if @tape.update(tape_params) - redirect_to @tape - else - render :edit, status: :unprocessable_entity - end - end - - def destroy - @tape.destroy - redirect_to tapes_path - end - - private - def set_tape - @tape = Tape.find(params[:id]) - end - - def tape_params - params.expect(tape: [ :title, :video ]) - 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/helpers/clips_helper.rb b/app/helpers/clips_helper.rb new file mode 100644 index 0000000..131c1f9 --- /dev/null +++ b/app/helpers/clips_helper.rb @@ -0,0 +1,9 @@ +module ClipsHelper + def seconds_to_time(seconds) + if seconds >= 3600 then + Time.at(seconds.round).utc.strftime("%H:%M:%S") #=> "01:00:00" + else + Time.at(seconds.round).utc.strftime("%M:%S") #=> "01:00:00" + end + end +end diff --git a/app/helpers/tapes_helper.rb b/app/helpers/tapes_helper.rb deleted file mode 100644 index 9f2b0b0..0000000 --- a/app/helpers/tapes_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module TapesHelper -end diff --git a/app/models/category.rb b/app/models/category.rb new file mode 100644 index 0000000..89e0619 --- /dev/null +++ b/app/models/category.rb @@ -0,0 +1,3 @@ +class Category < ApplicationRecord + has_many :clips +end diff --git a/app/models/tape.rb b/app/models/clip.rb similarity index 54% rename from app/models/tape.rb rename to app/models/clip.rb index ddd6bf3..005bbea 100644 --- a/app/models/tape.rb +++ b/app/models/clip.rb @@ -1,4 +1,5 @@ -class Tape < ApplicationRecord +class Clip < ApplicationRecord has_one_attached :video + belongs_to :category validates :title, presence: true end diff --git a/app/views/categories/_form.html.erb b/app/views/categories/_form.html.erb new file mode 100644 index 0000000..e36d9d4 --- /dev/null +++ b/app/views/categories/_form.html.erb @@ -0,0 +1,10 @@ +<%= form_with model: category do |form| %> +
+ <%= form.label :name %> + <%= form.text_field :name %> +
+ +
+ <%= form.submit %> +
+<% end %> \ No newline at end of file diff --git a/app/views/categories/edit.html.erb b/app/views/categories/edit.html.erb new file mode 100644 index 0000000..e39f429 --- /dev/null +++ b/app/views/categories/edit.html.erb @@ -0,0 +1,4 @@ +

Edit category

+ +<%= render "form", category: @category %> +<%= link_to "Cancel", @category %> \ No newline at end of file diff --git a/app/views/categories/index.html.erb b/app/views/categories/index.html.erb new file mode 100644 index 0000000..9f3d5ad --- /dev/null +++ b/app/views/categories/index.html.erb @@ -0,0 +1,9 @@ +

Categories

+ +<%= link_to "New category", new_category_path if authenticated? %> + + \ 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..5d71c1a --- /dev/null +++ b/app/views/categories/new.html.erb @@ -0,0 +1,4 @@ +

New Category

+ +<%= render "form", category: @category %> +<%= link_to "Cancel", categories_path %> \ No newline at end of file diff --git a/app/views/categories/show.html.erb b/app/views/categories/show.html.erb new file mode 100644 index 0000000..a93e8a1 --- /dev/null +++ b/app/views/categories/show.html.erb @@ -0,0 +1,42 @@ +<% cache @category do %> +

<%= @category.name %>

+<% end %> + + + + + + + + + + + <% @clips.each do |clip| %> + + + + + + + + + <% end %> +
PreviewTitleDurationCategoryUpdated atCreated at
+ <%= link_to (image_tag url_for(clip.video.preview(resize_to_limit: [160, 120]).processed)), clip %> + + <%= link_to clip.title, clip %> + + <%= seconds_to_time(clip.video.metadata["duration"]) %> + + <%= clip.category.name %> + + <%= clip.updated_at %> + + <%= clip.created_at %> +
+ +<%= link_to "Back", categories_path%> +<% if authenticated? %> + <%= link_to "Edit", edit_category_path(@category) %> + <%= button_to "Delete", @category, method: :delete, data: { turbo_confirm: "Are you sure?" } %> +<% end %> \ No newline at end of file diff --git a/app/views/tapes/_form.html.erb b/app/views/clips/_form.html.erb similarity index 60% rename from app/views/tapes/_form.html.erb rename to app/views/clips/_form.html.erb index 114fc78..43ccea0 100644 --- a/app/views/tapes/_form.html.erb +++ b/app/views/clips/_form.html.erb @@ -1,8 +1,9 @@ -<%= form_with model: tape do |form| %> +<%= form_with model: clip do |form| %>
<%= form.label :title %> <%= form.text_field :title %> <%= form.file_field :video, :accept => 'video/quicktime,video/mp4' %> + <%= form.select :category_id, Category.all.collect{ |t| [ t.name, t.id ] }%>
diff --git a/app/views/clips/edit.html.erb b/app/views/clips/edit.html.erb new file mode 100644 index 0000000..2ec8eb0 --- /dev/null +++ b/app/views/clips/edit.html.erb @@ -0,0 +1,4 @@ +

Edit clip

+ +<%= render "form", clip: @clip %> +<%= link_to "Cancel", @clip %> \ No newline at end of file diff --git a/app/views/clips/index.html.erb b/app/views/clips/index.html.erb new file mode 100644 index 0000000..2f08464 --- /dev/null +++ b/app/views/clips/index.html.erb @@ -0,0 +1,36 @@ +

Clips

+ +<%= link_to "New clip", new_clip_path if authenticated? %> + + + + + + + + + + + <% @clips.each do |clip| %> + + + + + + + + + <% end %> +
PreviewTitleDurationCategoryUpdated atCreated at
+ <%= link_to (image_tag url_for(clip.video.preview(resize_to_limit: [160, 120]).processed)), clip %> + + <%= link_to clip.title, clip %> + + <%= seconds_to_time(clip.video.metadata["duration"]) %> + + <%= clip.category.name %> + + <%= clip.updated_at %> + + <%= clip.created_at %> +
\ No newline at end of file diff --git a/app/views/clips/new.html.erb b/app/views/clips/new.html.erb new file mode 100644 index 0000000..1d5b7b4 --- /dev/null +++ b/app/views/clips/new.html.erb @@ -0,0 +1,4 @@ +

New Clip

+ +<%= render "form", clip: @clip %> +<%= link_to "Cancel", clips_path %> \ No newline at end of file diff --git a/app/views/clips/show.html.erb b/app/views/clips/show.html.erb new file mode 100644 index 0000000..00498c7 --- /dev/null +++ b/app/views/clips/show.html.erb @@ -0,0 +1,12 @@ +<% cache @clip do %> +

<%= @clip.title %>

+<% end %> +Category: <%= link_to @clip.category.name, @clip.category %>
+<% if @clip.video.attached? %> +<%= video_tag @clip.video, :controls => true%> +<% end %> +<%= link_to "Back", clips_path%> +<% if authenticated? %> + <%= link_to "Edit", edit_clip_path(@clip) %> + <%= button_to "Delete", @clip, method: :delete, data: { turbo_confirm: "Are you sure?" } %> +<% end %> \ No newline at end of file diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb index bf12125..fe2a98b 100644 --- a/app/views/home/index.html.erb +++ b/app/views/home/index.html.erb @@ -1,8 +1,8 @@

Recently Updated

-