Podcast ownership join table (MLH Fellowship #81) (#11410)

* added podcast_ownership route

* added podcast_ownership table

* added podcast_ownership controller and pundit policy

* fixed codeclimate

* removed controller and pundit policy

* codeclimate

* codeclimate

* schema.rb

* schema.rb

* schema.rb

* user.rb

* made the suggested changes

* added validations

* fixed build error

* changed name to owned_podcasts

* added validation and tests

* added tests

* added tests

* changed spec

* added factory

* added factory

* merge conflict

* factory

* factory

* factory

* modified spec file

* modified spec file

* fix build error

* added class_name

* adjusted m2m relations

* made suggested changes

* fixed build error

* added subject

* schema

* ran migration

* removed index:true from singular fields

* changed schema file

* set index: false
This commit is contained in:
Manasa 2020-11-19 17:11:17 +05:30 committed by GitHub
parent 7c5794dcda
commit b015690f4f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 61 additions and 2 deletions

View file

@ -2,8 +2,13 @@ class Podcast < ApplicationRecord
resourcify
belongs_to :creator, class_name: "User", inverse_of: :created_podcasts, optional: true
has_many :podcast_episodes, dependent: :destroy
# order here is important, the :through association has to be defined after the m2m
has_many :podcast_ownerships, dependent: :destroy
has_many :owners, through: :podcast_ownerships
mount_uploader :image, ProfileImageUploader
mount_uploader :pattern_image, ProfileImageUploader

View file

@ -0,0 +1,7 @@
class PodcastOwnership < ApplicationRecord
belongs_to :owner, class_name: "User", foreign_key: :user_id, inverse_of: :podcasts_owned
belongs_to :podcast
validates :podcast_id, uniqueness: { scope: :user_id }
validates :podcast_id, :user_id, presence: true
end

View file

@ -116,10 +116,10 @@ class User < ApplicationRecord
inverse_of: :offender, foreign_key: :offender_id, dependent: :nullify
has_many :organization_memberships, dependent: :destroy
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_ownerships, dependent: :destroy, inverse_of: :owner
has_many :podcasts_owned, through: :podcast_ownerships, source: :podcast
has_many :poll_skips, dependent: :destroy
has_many :poll_votes, dependent: :destroy
has_many :profile_pins, as: :profile, inverse_of: :profile, dependent: :delete_all

View file

@ -0,0 +1,10 @@
class CreatePodcastOwnerships < ActiveRecord::Migration[6.0]
def change
create_table :podcast_ownerships do |t|
t.references :podcast, foreign_key: true, index: false, null: false
t.references :user, foreign_key: true, index: false, null: false
t.timestamps
end
add_index :podcast_ownerships, %i[podcast_id user_id], unique: true
end
end

View file

@ -878,6 +878,14 @@ ActiveRecord::Schema.define(version: 2020_11_14_151157) do
t.index ["website_url"], name: "index_podcast_episodes_on_website_url"
end
create_table "podcast_ownerships", force: :cascade do |t|
t.datetime "created_at", precision: 6, null: false
t.bigint "podcast_id", null: false
t.datetime "updated_at", precision: 6, null: false
t.bigint "user_id", null: false
t.index ["podcast_id", "user_id"], name: "index_podcast_ownerships_on_podcast_id_and_user_id", unique: true
end
create_table "podcasts", force: :cascade do |t|
t.string "android_url"
t.datetime "created_at", null: false
@ -1427,6 +1435,8 @@ ActiveRecord::Schema.define(version: 2020_11_14_151157) do
add_foreign_key "page_views", "articles", on_delete: :cascade
add_foreign_key "page_views", "users", on_delete: :nullify
add_foreign_key "podcast_episodes", "podcasts", on_delete: :cascade
add_foreign_key "podcast_ownerships", "podcasts"
add_foreign_key "podcast_ownerships", "users"
add_foreign_key "podcasts", "users", column: "creator_id"
add_foreign_key "poll_options", "polls", on_delete: :cascade
add_foreign_key "poll_skips", "polls", on_delete: :cascade

View file

@ -0,0 +1,6 @@
FactoryBot.define do
factory :podcast_ownership do
owner factory: :user
podcast
end
end

View file

@ -0,0 +1,16 @@
require "rails_helper"
RSpec.describe PodcastOwnership, type: :model do
let(:podcast_ownership) { create(:podcast_ownership) }
describe "validations" do
subject { podcast_ownership }
it { is_expected.to belong_to(:owner).class_name("User").with_foreign_key(:user_id).inverse_of(:podcasts_owned) }
it { is_expected.to belong_to(:podcast) }
it { is_expected.to validate_presence_of(:podcast_id) }
it { is_expected.to validate_presence_of(:user_id) }
it { is_expected.to validate_uniqueness_of(:podcast_id).scoped_to(:user_id) }
end
end

View file

@ -22,7 +22,10 @@ RSpec.describe Podcast, type: :model do
subject { podcast }
it { is_expected.to belong_to(:creator).class_name("User").inverse_of(:created_podcasts).optional }
it { is_expected.to have_many(:owners).through(:podcast_ownerships) }
it { is_expected.to have_many(:podcast_episodes).dependent(:destroy) }
it { is_expected.to have_many(:podcast_ownerships).dependent(:destroy) }
it { is_expected.to validate_presence_of(:feed_url) }
it { is_expected.to validate_presence_of(:image) }

View file

@ -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_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) }
it { is_expected.to have_many(:poll_votes).dependent(:destroy) }
it { is_expected.to have_many(:profile_pins).dependent(:delete_all) }