diff --git a/app/controllers/clips_controller.rb b/app/controllers/clips_controller.rb index 6fceeff..81b4ece 100644 --- a/app/controllers/clips_controller.rb +++ b/app/controllers/clips_controller.rb @@ -15,6 +15,13 @@ class ClipsController < ApplicationController def create @clip = Clip.new(clip_params) if @clip.save + params[:clip][:tag_ids].each do |tag_id| + unless tag_id.empty? + tag = Tag.find(tag_id) + @clip.tags << tag + end + end + redirect_to @clip else render :new, status: :unprocessable_entity @@ -24,8 +31,25 @@ class ClipsController < ApplicationController def edit end - def update + def update if @clip.update(clip_params) + newtags = [] + params[:clip][:tag_ids].each do |tag_id| + unless tag_id.empty? + tag = Tag.find(tag_id) + newtags.push(tag) + unless @clip.tags.include? tag + @clip.tags << tag + end + end + end + + @clip.tags.each do |tag| + unless newtags.include? tag + @clip.tags.delete tag + end + end + redirect_to @clip else render :edit, status: :unprocessable_entity diff --git a/app/helpers/tag_to_clips_helper.rb b/app/helpers/tag_to_clips_helper.rb new file mode 100644 index 0000000..48c849c --- /dev/null +++ b/app/helpers/tag_to_clips_helper.rb @@ -0,0 +1,2 @@ +module TagToClipsHelper +end diff --git a/app/models/clip.rb b/app/models/clip.rb index 005bbea..1588fe7 100644 --- a/app/models/clip.rb +++ b/app/models/clip.rb @@ -1,5 +1,7 @@ class Clip < ApplicationRecord has_one_attached :video belongs_to :category + has_many :tag_to_clips + has_many :tags, through: :tag_to_clips validates :title, presence: true end diff --git a/app/models/tag.rb b/app/models/tag.rb new file mode 100644 index 0000000..f0ac3f0 --- /dev/null +++ b/app/models/tag.rb @@ -0,0 +1,4 @@ +class Tag < ApplicationRecord + has_many :tag_to_clips + has_many :clips, through: :tag_to_clips +end diff --git a/app/models/tag_to_clip.rb b/app/models/tag_to_clip.rb new file mode 100644 index 0000000..0313a65 --- /dev/null +++ b/app/models/tag_to_clip.rb @@ -0,0 +1,4 @@ +class TagToClip < ApplicationRecord + belongs_to :clip + belongs_to :tag +end diff --git a/app/views/clips/_form.html.erb b/app/views/clips/_form.html.erb index 43ccea0..b0aa46b 100644 --- a/app/views/clips/_form.html.erb +++ b/app/views/clips/_form.html.erb @@ -4,6 +4,7 @@ <%= 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 ] }%> + <%= collection_select(:clip, :tag_ids, Tag.all, :id, :name, {}, { :multiple => true } )%>
diff --git a/app/views/clips/show.html.erb b/app/views/clips/show.html.erb index 00498c7..7bd66ef 100644 --- a/app/views/clips/show.html.erb +++ b/app/views/clips/show.html.erb @@ -2,6 +2,7 @@

<%= @clip.title %>

<% end %> Category: <%= link_to @clip.category.name, @clip.category %>
+Tags: <%= @clip.tags.map(&:name).join(', ') %>
<% if @clip.video.attached? %> <%= video_tag @clip.video, :controls => true%> <% end %> diff --git a/config/routes.rb b/config/routes.rb index 68e0863..c6a7087 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,5 @@ Rails.application.routes.draw do + resources :tag_to_clips resource :session resources :passwords, param: :token # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html diff --git a/db/migrate/20250910022523_create_tags.rb b/db/migrate/20250910022523_create_tags.rb new file mode 100644 index 0000000..3337e26 --- /dev/null +++ b/db/migrate/20250910022523_create_tags.rb @@ -0,0 +1,9 @@ +class CreateTags < ActiveRecord::Migration[8.0] + def change + create_table :tags do |t| + t.string :name + + t.timestamps + end + end +end diff --git a/db/migrate/20250910022600_create_tag_to_clips.rb b/db/migrate/20250910022600_create_tag_to_clips.rb new file mode 100644 index 0000000..b4d47e1 --- /dev/null +++ b/db/migrate/20250910022600_create_tag_to_clips.rb @@ -0,0 +1,10 @@ +class CreateTagToClips < ActiveRecord::Migration[8.0] + def change + create_table :tag_to_clips do |t| + t.references :clip, null: false, foreign_key: true + t.references :tag, null: false, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index c7b1d60..fd62891 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2025_09_09_013509) do +ActiveRecord::Schema[8.0].define(version: 2025_09_10_022600) do create_table "active_storage_attachments", force: :cascade do |t| t.string "name", null: false t.string "record_type", null: false @@ -62,6 +62,21 @@ ActiveRecord::Schema[8.0].define(version: 2025_09_09_013509) do t.index ["user_id"], name: "index_sessions_on_user_id" end + create_table "tag_to_clips", force: :cascade do |t| + t.integer "clip_id", null: false + t.integer "tag_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["clip_id"], name: "index_tag_to_clips_on_clip_id" + t.index ["tag_id"], name: "index_tag_to_clips_on_tag_id" + end + + create_table "tags", force: :cascade do |t| + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "users", force: :cascade do |t| t.string "email_address", null: false t.string "password_digest", null: false @@ -74,4 +89,6 @@ ActiveRecord::Schema[8.0].define(version: 2025_09_09_013509) do add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" add_foreign_key "clips", "categories" add_foreign_key "sessions", "users" + add_foreign_key "tag_to_clips", "clips" + add_foreign_key "tag_to_clips", "tags" end diff --git a/test/controllers/tag_to_clips_controller_test.rb b/test/controllers/tag_to_clips_controller_test.rb new file mode 100644 index 0000000..a1fa563 --- /dev/null +++ b/test/controllers/tag_to_clips_controller_test.rb @@ -0,0 +1,48 @@ +require "test_helper" + +class TagToClipsControllerTest < ActionDispatch::IntegrationTest + setup do + @tag_to_clip = tag_to_clips(:one) + end + + test "should get index" do + get tag_to_clips_url + assert_response :success + end + + test "should get new" do + get new_tag_to_clip_url + assert_response :success + end + + test "should create tag_to_clip" do + assert_difference("TagToClip.count") do + post tag_to_clips_url, params: { tag_to_clip: { clip_id: @tag_to_clip.clip_id, tag_id: @tag_to_clip.tag_id } } + end + + assert_redirected_to tag_to_clip_url(TagToClip.last) + end + + test "should show tag_to_clip" do + get tag_to_clip_url(@tag_to_clip) + assert_response :success + end + + test "should get edit" do + get edit_tag_to_clip_url(@tag_to_clip) + assert_response :success + end + + test "should update tag_to_clip" do + patch tag_to_clip_url(@tag_to_clip), params: { tag_to_clip: { clip_id: @tag_to_clip.clip_id, tag_id: @tag_to_clip.tag_id } } + assert_redirected_to tag_to_clip_url(@tag_to_clip) + end + + test "should destroy tag_to_clip" do + assert_difference("TagToClip.count", -1) do + delete tag_to_clip_url(@tag_to_clip) + end + + assert_redirected_to tag_to_clips_url + end +end diff --git a/test/fixtures/tag_to_clips.yml b/test/fixtures/tag_to_clips.yml new file mode 100644 index 0000000..0105b24 --- /dev/null +++ b/test/fixtures/tag_to_clips.yml @@ -0,0 +1,9 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + clip: one + tag: one + +two: + clip: two + tag: two diff --git a/test/fixtures/tags.yml b/test/fixtures/tags.yml new file mode 100644 index 0000000..7d41224 --- /dev/null +++ b/test/fixtures/tags.yml @@ -0,0 +1,7 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + +two: + name: MyString diff --git a/test/models/tag_test.rb b/test/models/tag_test.rb new file mode 100644 index 0000000..1846cdb --- /dev/null +++ b/test/models/tag_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class TagTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/tag_to_clip_test.rb b/test/models/tag_to_clip_test.rb new file mode 100644 index 0000000..d841e0e --- /dev/null +++ b/test/models/tag_to_clip_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class TagToClipTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end