Add podcast_appearances joined table (forem#82) (#11354)
* Add podcast_appearances joined table (forem#82) * Add podcast appearances keys unique constraint and creator property (forem#82) * Add podcast_appearance role validation forem(#82) * Add spec test for podcast_appearances model (forem#82) * Small refactoring - place podcast appearance association by alphabetical order * Adapt m2m association to pass rspec test (forem#82) * Rename podcast appearance model to podcast episode appearance and remove fk indexing * Rename podcast appearance model to podcast episode appearance and remove fk indexing * Rename podcast episode appearance models and spec models. Update podcast episode and user spec tests (forem#82) * Rename podcast episode appearances composite index to follow Rails naming pattern (forem#82) * Remove ddl_transaction disabling and conurrent index adding from appearance migration * Add role validation in model spec (forem#82)
This commit is contained in:
parent
d43ff0d46c
commit
ad04158b90
9 changed files with 75 additions and 1 deletions
|
|
@ -16,6 +16,8 @@ class PodcastEpisode < ApplicationRecord
|
|||
|
||||
belongs_to :podcast
|
||||
has_many :comments, as: :commentable, inverse_of: :commentable, dependent: :nullify
|
||||
has_many :podcast_episode_appearances, dependent: :destroy
|
||||
has_many :users, through: :podcast_episode_appearances
|
||||
|
||||
mount_uploader :image, ProfileImageUploader
|
||||
mount_uploader :social_image, ProfileImageUploader
|
||||
|
|
|
|||
7
app/models/podcast_episode_appearance.rb
Normal file
7
app/models/podcast_episode_appearance.rb
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
class PodcastEpisodeAppearance < ApplicationRecord
|
||||
belongs_to :user, class_name: "User", inverse_of: :podcast_episode_appearances
|
||||
belongs_to :podcast_episode
|
||||
validates :podcast_episode_id, uniqueness: { scope: :user_id }
|
||||
validates :podcast_episode_id, :user_id, :role, presence: true
|
||||
validates :role, inclusion: { in: %w[host guest], message: "provided role is not valid" }
|
||||
end
|
||||
|
|
@ -118,6 +118,8 @@ class User < ApplicationRecord
|
|||
has_many :organizations, through: :organization_memberships
|
||||
# we keep page views as they belong to the article, not to the user who viewed it
|
||||
has_many :page_views, dependent: :nullify
|
||||
has_many :podcast_episode_appearances, dependent: :destroy, inverse_of: :user
|
||||
has_many :podcast_episodes, through: :podcast_episode_appearances, source: :podcast_episode
|
||||
has_many :podcast_ownerships, dependent: :destroy, inverse_of: :owner
|
||||
has_many :podcasts_owned, through: :podcast_ownerships, source: :podcast
|
||||
has_many :poll_skips, dependent: :destroy
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
class CreatePodcastEpisodeAppearances < ActiveRecord::Migration[6.0]
|
||||
def change
|
||||
create_table :podcast_episode_appearances do |t|
|
||||
t.references :user, null: false, foreign_key: true, index: false
|
||||
t.references :podcast_episode, null: false, foreign_key: true, index: false
|
||||
t.string :role, null: false, default: "guest"
|
||||
t.boolean :approved, null: false, default: false
|
||||
t.boolean :featured_on_user_profile, null: false, default: false
|
||||
t.timestamps
|
||||
end
|
||||
add_index :podcast_episode_appearances,
|
||||
%i[podcast_episode_id user_id],
|
||||
unique: true,
|
||||
name: "index_pod_episode_appearances_on_podcast_episode_id_and_user_id"
|
||||
end
|
||||
end
|
||||
15
db/schema.rb
15
db/schema.rb
|
|
@ -10,8 +10,8 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2020_11_19_153512) do
|
||||
|
||||
ActiveRecord::Schema.define(version: 2020_11_19_153512) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "citext"
|
||||
enable_extension "pgcrypto"
|
||||
|
|
@ -848,6 +848,17 @@ ActiveRecord::Schema.define(version: 2020_11_19_153512) do
|
|||
t.index ["slug"], name: "index_pages_on_slug", unique: true
|
||||
end
|
||||
|
||||
create_table "podcast_episode_appearances", force: :cascade do |t|
|
||||
t.boolean "approved", default: false, null: false
|
||||
t.datetime "created_at", precision: 6, null: false
|
||||
t.boolean "featured_on_user_profile", default: false, null: false
|
||||
t.bigint "podcast_episode_id", null: false
|
||||
t.string "role", default: "guest", null: false
|
||||
t.datetime "updated_at", precision: 6, null: false
|
||||
t.bigint "user_id", null: false
|
||||
t.index ["podcast_episode_id", "user_id"], name: "index_pod_episode_appearances_on_podcast_episode_id_and_user_id", unique: true
|
||||
end
|
||||
|
||||
create_table "podcast_episodes", force: :cascade do |t|
|
||||
t.boolean "any_comments_hidden", default: false
|
||||
t.text "body"
|
||||
|
|
@ -1436,6 +1447,8 @@ ActiveRecord::Schema.define(version: 2020_11_19_153512) do
|
|||
add_foreign_key "organization_memberships", "users", on_delete: :cascade
|
||||
add_foreign_key "page_views", "articles", on_delete: :cascade
|
||||
add_foreign_key "page_views", "users", on_delete: :nullify
|
||||
add_foreign_key "podcast_episode_appearances", "podcast_episodes"
|
||||
add_foreign_key "podcast_episode_appearances", "users"
|
||||
add_foreign_key "podcast_episodes", "podcasts", on_delete: :cascade
|
||||
add_foreign_key "podcast_ownerships", "podcasts"
|
||||
add_foreign_key "podcast_ownerships", "users"
|
||||
|
|
|
|||
7
spec/factories/podcast_episode_appearances.rb
Normal file
7
spec/factories/podcast_episode_appearances.rb
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
FactoryBot.define do
|
||||
factory :podcast_episode_appearance do
|
||||
user
|
||||
podcast_episode
|
||||
role { "guest" }
|
||||
end
|
||||
end
|
||||
23
spec/models/podcast_episode_appearance_spec.rb
Normal file
23
spec/models/podcast_episode_appearance_spec.rb
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe PodcastEpisodeAppearance, type: :model do
|
||||
let(:podcast_episode_appearance) { create(:podcast_episode_appearance) }
|
||||
|
||||
describe "validations" do
|
||||
subject { podcast_episode_appearance }
|
||||
|
||||
it { is_expected.to belong_to(:user).inverse_of(:podcast_episode_appearances) }
|
||||
it { is_expected.to belong_to(:podcast_episode) }
|
||||
|
||||
it { is_expected.to validate_presence_of(:podcast_episode_id) }
|
||||
it { is_expected.to validate_presence_of(:user_id) }
|
||||
it { is_expected.to validate_presence_of(:role) }
|
||||
|
||||
it do
|
||||
expect(podcast_episode_appearance).to validate_inclusion_of(:role).in_array(%w[host guest])
|
||||
.with_message("provided role is not valid")
|
||||
end
|
||||
|
||||
it { is_expected.to validate_uniqueness_of(:podcast_episode_id).scoped_to(:user_id) }
|
||||
end
|
||||
end
|
||||
|
|
@ -9,6 +9,8 @@ RSpec.describe PodcastEpisode, type: :model do
|
|||
|
||||
it { is_expected.to belong_to(:podcast) }
|
||||
it { is_expected.to have_many(:comments).inverse_of(:commentable).dependent(:nullify) }
|
||||
it { is_expected.to have_many(:podcast_episode_appearances).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:users).through(:podcast_episode_appearances) }
|
||||
|
||||
it { is_expected.to validate_presence_of(:comments_count) }
|
||||
it { is_expected.to validate_presence_of(:guid) }
|
||||
|
|
|
|||
|
|
@ -68,6 +68,8 @@ RSpec.describe User, type: :model do
|
|||
it { is_expected.to have_many(:organization_memberships).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:organizations).through(:organization_memberships) }
|
||||
it { is_expected.to have_many(:page_views).dependent(:nullify) }
|
||||
it { is_expected.to have_many(:podcast_episode_appearances).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:podcast_episodes).through(:podcast_episode_appearances).source(:podcast_episode) }
|
||||
it { is_expected.to have_many(:podcast_ownerships).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:podcasts_owned).through(:podcast_ownerships).source(:podcast) }
|
||||
it { is_expected.to have_many(:poll_skips).dependent(:destroy) }
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue