From 5e54a63308f87c013857abe50ca747aa7c419e85 Mon Sep 17 00:00:00 2001 From: OmarMWarraich Date: Wed, 24 Jul 2024 00:14:34 +0500 Subject: [PATCH] feat: Subscription Model --- app/controllers/subscriptions_controller.rb | 24 ++++++++++++ app/models/subscription.rb | 26 +++++++++++++ app/models/user.rb | 16 +++++--- app/views/subscriptions/index.html.erb | 20 +++++----- app/views/subscriptions/success.html.erb | 3 +- config/routes.rb | 12 +++--- .../20240723185719_create_subscriptions.rb | 15 +++++++ ...185845_add_stripe_customer_ref_to_users.rb | 6 +++ db/schema.rb | 18 ++++++++- test/fixtures/subscriptions.yml | 39 +++++++++++++++++++ test/fixtures/users.yml | 15 ++++--- test/models/subscription_test.rb | 30 ++++++++++++++ test/models/user_test.rb | 15 ++++--- 13 files changed, 205 insertions(+), 34 deletions(-) create mode 100644 app/models/subscription.rb create mode 100644 db/migrate/20240723185719_create_subscriptions.rb create mode 100644 db/migrate/20240723185845_add_stripe_customer_ref_to_users.rb create mode 100644 test/fixtures/subscriptions.yml create mode 100644 test/models/subscription_test.rb diff --git a/app/controllers/subscriptions_controller.rb b/app/controllers/subscriptions_controller.rb index 2bac043..ac4810f 100644 --- a/app/controllers/subscriptions_controller.rb +++ b/app/controllers/subscriptions_controller.rb @@ -1,7 +1,31 @@ class SubscriptionsController < ApplicationController + before_action :authenticate_user! def index end def success end + + def create_checkout_session + prices = Stripe::Price.list( + lookup_keys: [params['lookup_key']], + expand: ['data.product'] + ) + + subscription = current_user.subscriptions.find_or_create_by(status: "pending") + + session = Stripe::Checkout::Session.create({ + mode: 'subscription', + client_reference_id: subscription.id, + customer_email: current_user.email, + line_items: [{ + quantity: 1, + price: prices.data[0].id + }], + success_url: "http://localhost:3000" + '/success.html?session_id={CHECKOUT_SESSION_ID}', + cancel_url: root_url, + }) + + redirect_to session.url, 303, allow_other_host: true + end end diff --git a/app/models/subscription.rb b/app/models/subscription.rb new file mode 100644 index 0000000..d9bf96c --- /dev/null +++ b/app/models/subscription.rb @@ -0,0 +1,26 @@ +# == Schema Information +# +# Table name: subscriptions +# +# id :bigint not null, primary key +# next_invoice_on :datetime +# paid_until :datetime +# status :string +# stripe_customer_ref :string +# stripe_subscription_ref :string +# created_at :datetime not null +# updated_at :datetime not null +# user_id :bigint not null +# +# Indexes +# +# index_subscriptions_on_stripe_subscription_ref (stripe_subscription_ref) UNIQUE +# index_subscriptions_on_user_id (user_id) +# +# Foreign Keys +# +# fk_rails_... (user_id => users.id) +# +class Subscription < ApplicationRecord + belongs_to :user +end diff --git a/app/models/user.rb b/app/models/user.rb index 890c795..8c44ab4 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -2,11 +2,16 @@ # # Table name: users # -# id :bigint not null, primary key -# email :string -# password_digest :string -# created_at :datetime not null -# updated_at :datetime not null +# id :bigint not null, primary key +# email :string +# password_digest :string +# stripe_customer_ref :string +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_users_on_stripe_customer_ref (stripe_customer_ref) UNIQUE # class User < ApplicationRecord has_secure_password @@ -15,6 +20,7 @@ class User < ApplicationRecord normalizes :email, with: ->(email) { email.strip.downcase } has_many :generated_images, dependent: :destroy + has_many :subscriptions, dependent: :destroy generates_token_for :password_reset, expires_in: 10.minutes do password_salt&.last(10) diff --git a/app/views/subscriptions/index.html.erb b/app/views/subscriptions/index.html.erb index f0bc241..c396b8f 100644 --- a/app/views/subscriptions/index.html.erb +++ b/app/views/subscriptions/index.html.erb @@ -1,13 +1,15 @@ -
+ + +
+
+
-

Starter plan

-
$20.00 / month
+

Basic plan

+
$10.00 / month
-
- - - -
-
\ No newline at end of file + <%= button_to "Signup", create_checkout_session_path(lookup_key: "image_gen_basic"), data: { turbo: false }, class: "btn btn-primary" %> +
+ + \ No newline at end of file diff --git a/app/views/subscriptions/success.html.erb b/app/views/subscriptions/success.html.erb index 35cb049..5174600 100644 --- a/app/views/subscriptions/success.html.erb +++ b/app/views/subscriptions/success.html.erb @@ -1,2 +1 @@ -

Subscriptions#success

-

Find me in app/views/subscriptions/success.html.erb

+Thank you for subscribing! \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 41231a1..809a975 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,11 +1,9 @@ Rails.application.routes.draw do - get 'pricing' => 'subscriptions#index' - get 'subscriptions/success' - # get 'generated_images/show' - # get 'txt2_imgs/index' - # get 'sessions/new' - # get 'registrations/new' - # get 'home/index' + get "pricing" => "subscriptions#index" + post "/create_checkout_session" => "subscriptions#create_checkout_session", as: :create_checkout_session + get "success" => "subscriptions#success" + + # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html resource :session # where login and logout routes are defined diff --git a/db/migrate/20240723185719_create_subscriptions.rb b/db/migrate/20240723185719_create_subscriptions.rb new file mode 100644 index 0000000..54e68d6 --- /dev/null +++ b/db/migrate/20240723185719_create_subscriptions.rb @@ -0,0 +1,15 @@ +class CreateSubscriptions < ActiveRecord::Migration[7.1] + def change + create_table :subscriptions do |t| + t.string :stripe_customer_ref + t.string :stripe_subscription_ref + t.datetime :next_invoice_on + t.datetime :paid_until + t.references :user, null: false, foreign_key: true + t.string :status + + t.timestamps + end + add_index :subscriptions, :stripe_subscription_ref, unique: true + end +end diff --git a/db/migrate/20240723185845_add_stripe_customer_ref_to_users.rb b/db/migrate/20240723185845_add_stripe_customer_ref_to_users.rb new file mode 100644 index 0000000..670ab7b --- /dev/null +++ b/db/migrate/20240723185845_add_stripe_customer_ref_to_users.rb @@ -0,0 +1,6 @@ +class AddStripeCustomerRefToUsers < ActiveRecord::Migration[7.1] + def change + add_column :users, :stripe_customer_ref, :string + add_index :users, :stripe_customer_ref, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 1edf723..1fa89da 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[7.1].define(version: 2024_07_01_221718) do +ActiveRecord::Schema[7.1].define(version: 2024_07_23_185845) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -64,15 +64,31 @@ t.index ["user_id"], name: "index_progress_holders_on_user_id" end + create_table "subscriptions", force: :cascade do |t| + t.string "stripe_customer_ref" + t.string "stripe_subscription_ref" + t.datetime "next_invoice_on" + t.datetime "paid_until" + t.bigint "user_id", null: false + t.string "status" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["stripe_subscription_ref"], name: "index_subscriptions_on_stripe_subscription_ref", unique: true + t.index ["user_id"], name: "index_subscriptions_on_user_id" + end + create_table "users", force: :cascade do |t| t.string "email" t.string "password_digest" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "stripe_customer_ref" + t.index ["stripe_customer_ref"], name: "index_users_on_stripe_customer_ref", unique: true end add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" add_foreign_key "generated_images", "users" add_foreign_key "progress_holders", "users" + add_foreign_key "subscriptions", "users" end diff --git a/test/fixtures/subscriptions.yml b/test/fixtures/subscriptions.yml new file mode 100644 index 0000000..bb430c0 --- /dev/null +++ b/test/fixtures/subscriptions.yml @@ -0,0 +1,39 @@ +# == Schema Information +# +# Table name: subscriptions +# +# id :bigint not null, primary key +# next_invoice_on :datetime +# paid_until :datetime +# status :string +# stripe_customer_ref :string +# stripe_subscription_ref :string +# created_at :datetime not null +# updated_at :datetime not null +# user_id :bigint not null +# +# Indexes +# +# index_subscriptions_on_stripe_subscription_ref (stripe_subscription_ref) UNIQUE +# index_subscriptions_on_user_id (user_id) +# +# Foreign Keys +# +# fk_rails_... (user_id => users.id) +# + +one: + stripe_customer_ref: MyString + stripe_subscription_ref: MyString + next_invoice_on: 2024-07-23 23:57:19 + paid_until: 2024-07-23 23:57:19 + user: one + status: MyString + +two: + stripe_customer_ref: MyString + stripe_subscription_ref: MyString + next_invoice_on: 2024-07-23 23:57:19 + paid_until: 2024-07-23 23:57:19 + user: two + status: MyString diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index 10a70b4..973913a 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -2,11 +2,16 @@ # # Table name: users # -# id :bigint not null, primary key -# email :string -# password_digest :string -# created_at :datetime not null -# updated_at :datetime not null +# id :bigint not null, primary key +# email :string +# password_digest :string +# stripe_customer_ref :string +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_users_on_stripe_customer_ref (stripe_customer_ref) UNIQUE # one: diff --git a/test/models/subscription_test.rb b/test/models/subscription_test.rb new file mode 100644 index 0000000..12e6139 --- /dev/null +++ b/test/models/subscription_test.rb @@ -0,0 +1,30 @@ +# == Schema Information +# +# Table name: subscriptions +# +# id :bigint not null, primary key +# next_invoice_on :datetime +# paid_until :datetime +# status :string +# stripe_customer_ref :string +# stripe_subscription_ref :string +# created_at :datetime not null +# updated_at :datetime not null +# user_id :bigint not null +# +# Indexes +# +# index_subscriptions_on_stripe_subscription_ref (stripe_subscription_ref) UNIQUE +# index_subscriptions_on_user_id (user_id) +# +# Foreign Keys +# +# fk_rails_... (user_id => users.id) +# +require "test_helper" + +class SubscriptionTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/user_test.rb b/test/models/user_test.rb index cfba810..16a8402 100644 --- a/test/models/user_test.rb +++ b/test/models/user_test.rb @@ -2,11 +2,16 @@ # # Table name: users # -# id :bigint not null, primary key -# email :string -# password_digest :string -# created_at :datetime not null -# updated_at :datetime not null +# id :bigint not null, primary key +# email :string +# password_digest :string +# stripe_customer_ref :string +# created_at :datetime not null +# updated_at :datetime not null +# +# Indexes +# +# index_users_on_stripe_customer_ref (stripe_customer_ref) UNIQUE # require "test_helper"