[deploy] Introduce ClassifiedListingCategory model (#7172)
* Add ClassifiedListingCategoryModel * Add data update script for classified listing categories * Add foreign key to reference * Move data update script to temporary rake task * Update factory * Add and fix specs * Fix typo * Fix migration * Correctly add unique index * Fix migration * Add slug column to classified listing categories * Add unique index for slug column
This commit is contained in:
parent
80737b5404
commit
ca23b8e1c6
9 changed files with 112 additions and 2 deletions
|
|
@ -4,6 +4,7 @@ class ClassifiedListing < ApplicationRecord
|
|||
SEARCH_SERIALIZER = Search::ClassifiedListingSerializer
|
||||
SEARCH_CLASS = Search::ClassifiedListing
|
||||
|
||||
# TODO: remove this once we are live with the new ClassifiedListingCategory model
|
||||
CATEGORIES_AVAILABLE = {
|
||||
cfp: { cost: 1, name: "Conference CFP", rules: "Currently open for proposals, with link to form." },
|
||||
forhire: { cost: 1, name: "Available for Hire", rules: "You are available for hire." },
|
||||
|
|
@ -18,8 +19,13 @@ class ClassifiedListing < ApplicationRecord
|
|||
misc: { cost: 1, name: "Miscellaneous", rules: "Must not fit in any other category." }
|
||||
}.with_indifferent_access.freeze
|
||||
|
||||
# TODO: remove this once we are live with the new ClassifiedListingCategory model
|
||||
before_validation :assign_classified_listing_category
|
||||
|
||||
attr_accessor :action
|
||||
|
||||
# TODO: this is optional for now to ease the migration
|
||||
belongs_to :classified_listing_category, optional: true
|
||||
belongs_to :user
|
||||
belongs_to :organization, optional: true
|
||||
before_save :evaluate_markdown
|
||||
|
|
@ -109,4 +115,12 @@ class ClassifiedListing < ApplicationRecord
|
|||
def create_slug
|
||||
self.slug = title.to_s.downcase.parameterize.tr("_", "") + "-" + rand(100_000).to_s(26)
|
||||
end
|
||||
|
||||
def assign_classified_listing_category
|
||||
category_name = CATEGORIES_AVAILABLE.dig(attributes["category"], :name)
|
||||
category = ClassifiedListingCategory.find_by(name: category_name)
|
||||
return unless category
|
||||
|
||||
self.classified_listing_category_id = category.id
|
||||
end
|
||||
end
|
||||
|
|
|
|||
6
app/models/classified_listing_category.rb
Normal file
6
app/models/classified_listing_category.rb
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
class ClassifiedListingCategory < ApplicationRecord
|
||||
has_many :classified_listings
|
||||
|
||||
validates :name, :cost, :rules, :slug, presence: true
|
||||
validates :name, :slug, uniqueness: true
|
||||
end
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
class CreateClassifiedListingCategories < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :classified_listing_categories do |t|
|
||||
t.string :name, null: false
|
||||
t.integer :cost, null: false
|
||||
t.string :rules, null: false
|
||||
t.string :slug, null: false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
add_index(:classified_listing_categories, :name, unique: true)
|
||||
add_index(:classified_listing_categories, :slug, unique: true)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
class AddListingCategoryToClassifiedListing < ActiveRecord::Migration[5.2]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def change
|
||||
add_reference :classified_listings,
|
||||
:classified_listing_category,
|
||||
foreign_key: true,
|
||||
index: { algorithm: :concurrently }
|
||||
end
|
||||
end
|
||||
17
db/schema.rb
17
db/schema.rb
|
|
@ -10,8 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2020_04_07_091449) do
|
||||
|
||||
ActiveRecord::Schema.define(version: 2020_04_09_050122) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
|
@ -311,11 +310,23 @@ ActiveRecord::Schema.define(version: 2020_04_07_091449) do
|
|||
t.index ["slug"], name: "index_chat_channels_on_slug", unique: true
|
||||
end
|
||||
|
||||
create_table "classified_listing_categories", force: :cascade do |t|
|
||||
t.integer "cost", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.string "name", null: false
|
||||
t.string "rules", null: false
|
||||
t.string "slug", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["name"], name: "index_classified_listing_categories_on_name", unique: true
|
||||
t.index ["slug"], name: "index_classified_listing_categories_on_slug", unique: true
|
||||
end
|
||||
|
||||
create_table "classified_listings", force: :cascade do |t|
|
||||
t.text "body_markdown"
|
||||
t.datetime "bumped_at"
|
||||
t.string "cached_tag_list"
|
||||
t.string "category"
|
||||
t.bigint "classified_listing_category_id"
|
||||
t.boolean "contact_via_connect", default: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "expires_at"
|
||||
|
|
@ -328,6 +339,7 @@ ActiveRecord::Schema.define(version: 2020_04_07_091449) do
|
|||
t.string "title"
|
||||
t.datetime "updated_at", null: false
|
||||
t.bigint "user_id"
|
||||
t.index ["classified_listing_category_id"], name: "index_classified_listings_on_classified_listing_category_id"
|
||||
t.index ["organization_id"], name: "index_classified_listings_on_organization_id"
|
||||
t.index ["user_id"], name: "index_classified_listings_on_user_id"
|
||||
end
|
||||
|
|
@ -1232,6 +1244,7 @@ ActiveRecord::Schema.define(version: 2020_04_07_091449) do
|
|||
add_foreign_key "badge_achievements", "users"
|
||||
add_foreign_key "chat_channel_memberships", "chat_channels"
|
||||
add_foreign_key "chat_channel_memberships", "users"
|
||||
add_foreign_key "classified_listings", "classified_listing_categories"
|
||||
add_foreign_key "classified_listings", "users", on_delete: :cascade
|
||||
add_foreign_key "email_authorizations", "users", on_delete: :cascade
|
||||
add_foreign_key "identities", "users", on_delete: :cascade
|
||||
|
|
|
|||
13
lib/tasks/temporary/classified_listings.rake
Normal file
13
lib/tasks/temporary/classified_listings.rake
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
namespace :temporary do
|
||||
namespace :classified_listings do
|
||||
desc "Backfill classified listings categories"
|
||||
task backfill_categories: :environment do
|
||||
ClassifiedListing::CATEGORIES_AVAILABLE.each do |key, attributes|
|
||||
category = ClassifiedListingCategory.find_or_create_by!(attributes.merge(slug: key))
|
||||
ClassifiedListing.
|
||||
where(category: key.to_s).
|
||||
update_all(classified_listing_category_id: category.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
12
spec/factories/classified_listing_categories.rb
Normal file
12
spec/factories/classified_listing_categories.rb
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
FactoryBot.define do
|
||||
factory :classified_listing_category do
|
||||
name { "Education/Courses" }
|
||||
cost { [1, 5, 25].sample }
|
||||
rules { Faker::Hipster.paragraph(sentence_count: 1) }
|
||||
slug { "education" }
|
||||
|
||||
trait :cfp do
|
||||
name { "Conference CFP" }
|
||||
end
|
||||
end
|
||||
end
|
||||
16
spec/models/classified_listing_category_spec.rb
Normal file
16
spec/models/classified_listing_category_spec.rb
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe ClassifiedListingCategory, type: :model do
|
||||
describe "validations" do
|
||||
# The uniqueness validation didn't work without this, see section "Caveat" at
|
||||
# https://www.rubydoc.info/github/thoughtbot/shoulda-matchers/Shoulda%2FMatchers%2FActiveRecord:validate_uniqueness_of
|
||||
subject { create(:classified_listing_category) }
|
||||
|
||||
it { is_expected.to validate_presence_of(:name) }
|
||||
it { is_expected.to validate_presence_of(:cost) }
|
||||
it { is_expected.to validate_presence_of(:rules) }
|
||||
it { is_expected.to validate_presence_of(:slug) }
|
||||
it { is_expected.to validate_uniqueness_of(:name) }
|
||||
it { is_expected.to validate_uniqueness_of(:slug) }
|
||||
end
|
||||
end
|
||||
|
|
@ -32,6 +32,18 @@ RSpec.describe ClassifiedListing, type: :model do
|
|||
end
|
||||
end
|
||||
|
||||
# TODO: remove this once we are live with the new ClassifiedListingCategory model
|
||||
describe "classified listing category" do
|
||||
it "automatically assigns a category on save" do
|
||||
create(:classified_listing_category)
|
||||
|
||||
cl = build(:classified_listing, user_id: user.id)
|
||||
cl.save
|
||||
expect(cl).to be_valid
|
||||
expect(cl.reload.classified_listing_category).to be_present
|
||||
end
|
||||
end
|
||||
|
||||
describe "body html" do
|
||||
it "converts markdown to html" do
|
||||
expect(classified_listing.processed_html).to include("<p>")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue