diff --git a/app/controllers/survey_controller.rb b/app/controllers/survey_controller.rb new file mode 100644 index 0000000..8a0b871 --- /dev/null +++ b/app/controllers/survey_controller.rb @@ -0,0 +1,20 @@ +class SurveyController < ApplicationController + before_action :authenticate_user! + + # If a user re-subscribes within the grace period, we don't want to process the job. + GRACE_PERIOD = 1.week + + def create + current_user.surveys.create(survey_param) + current_user.stop_active_subscriptions + SeeYouSoonJob.set(wait: GRACE_PERIOD).perform_later(current_user) + + redirect_to see_you_soon_path, notice: "We hope to see you again!" + end + + private + + def survey_param + params.require(:survey).permit(:description, :reason, :competitor_url) + end +end diff --git a/app/jobs/see_you_soon_job.rb b/app/jobs/see_you_soon_job.rb new file mode 100644 index 0000000..6d9ad4c --- /dev/null +++ b/app/jobs/see_you_soon_job.rb @@ -0,0 +1,9 @@ +class SeeYouSoonJob < ApplicationJob + queue_as :default + + # Delete all records that are part of the paid feature. + def perform(user) + user.posts.each { |post| post.destroy } + user.uploaded_pictures.each { |upload| upload.destroy } + end +end diff --git a/app/models/survey.rb b/app/models/survey.rb new file mode 100644 index 0000000..a045c15 --- /dev/null +++ b/app/models/survey.rb @@ -0,0 +1,22 @@ +class Survey < ApplicationRecord + REASONS = %w[expensive not_interested_anymore difficult_to_use other].freeze + + belongs_to :user + + validates :competitor_url, presence: true, format: { with: /\A^(http|https)\z/i } + validates :reason, presence: true + validate :reason_in_list + validate :description_required_if_other + + private + + def reason_in_list + errors.add(:reason, "not in list") if REASONS.exclude?(reason) + end + + def description_required_if_other + if reason == "other" && description.blank? + errors.add(:description, "cannot be blank") + end + end +end diff --git a/app/models/user.rb b/app/models/user.rb index 603da69..8a66451 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,3 +1,5 @@ class User < ApplicationRecord + has_many :surveys + validates :email, presence: true end diff --git a/config/routes.rb b/config/routes.rb index 1daf9a4..18061c9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,2 +1,3 @@ Rails.application.routes.draw do + resources :surveys, only: :create end diff --git a/db/migrate/20230509084017_create_surveys.rb b/db/migrate/20230509084017_create_surveys.rb new file mode 100644 index 0000000..0fec6d4 --- /dev/null +++ b/db/migrate/20230509084017_create_surveys.rb @@ -0,0 +1,13 @@ +class CreateSurveys < ActiveRecord::Migration[7.0] + def change + create_table :surveys do |t| + t.belongs_to :user, null: false, foreign_key: true + + t.string :competitor_url, null: false + t.text :description + t.string :reason, null: false + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 12949d2..3291fda 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,10 +10,20 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_05_09_082743) do +ActiveRecord::Schema[7.0].define(version: 2023_05_09_084017) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" + create_table "surveys", force: :cascade do |t| + t.bigint "user_id", null: false + t.string "competitor_url", null: false + t.text "description" + t.string "reason", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["user_id"], name: "index_surveys_on_user_id" + end + create_table "users", force: :cascade do |t| t.string "email", null: false t.datetime "created_at", null: false @@ -21,4 +31,5 @@ t.index ["email"], name: "index_users_on_email", unique: true end + add_foreign_key "surveys", "users" end