Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crud subscriptions #105

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/assets/stylesheets/subscription.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Place all the styles related to the Subscription controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: https://sass-lang.com/
57 changes: 57 additions & 0 deletions app/controllers/subscriptions_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# frozen_string_literal: true

class SubscriptionsController < ApplicationController
protect_from_forgery unless: -> { request.format.json? }

before_action :user, only: %i[new create destroy]
before_action :last_subscription, only: %i[destroy]

def index
@subscriptions = Subscription.all
end

def new
@subscription = @user.subscriptions.new
end

def create
@subscription = @user.add_subscription(subscription_params)
respond_to do |format|
if @subscription.save
format.html { redirect_to @user }
format.json { render 'show', status: :created }
else
format.html { render 'new' }
format.json { render json: @subscription.errors, status: :unprocessable_entity }
end
end
end

def destroy
@user.cancel_subscription(@last_subscription)
respond_to do |format|
format.html { redirect_to @user }
format.json { head :no_content }
end
end

private

def subscription_params
params.require(:subscription).permit(:duration)
end

def user
@user = User.find(params[:user_id])
end

def last_subscription
@last_subscription = @user.subscriptions.not_cancelled.last
return if @last_subscription

respond_to do |format|
format.html { redirect_to @user }
format.json { render json: { error: 'There is no subscription' }, status: :unprocessable_entity }
end
end
end
4 changes: 4 additions & 0 deletions app/helpers/subscription_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

module SubscriptionHelper
end
31 changes: 31 additions & 0 deletions app/models/subscription.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

class Subscription < ApplicationRecord
@monthly_price = 8
@yearly_price = 80

scope :not_cancelled, -> { where(cancelled_date: nil) }

belongs_to :user

validates :duration, presence: true, numericality: { only_integer: true, greater_than: 0 }

# Definition of class instance variables
class << self
attr_accessor :monthly_price, :yearly_price
end

def price
return unless duration

((duration / 12) * Subscription.yearly_price + (duration % 12) * Subscription.monthly_price)
end

def cancelled
!!cancelled_date
end

def toggle_cancelled
self.cancelled_date = cancelled_date ? nil : DateTime.now
end
end
30 changes: 30 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

class User < ApplicationRecord
has_many :machines, dependent: :destroy
has_many :subscriptions, dependent: :destroy

before_save :downcase_email
before_save :format_room
Expand All @@ -13,6 +14,35 @@ class User < ApplicationRecord
VALID_ROOM_REGEX = /\A([A-F][0-3][0-9]{2}[a-b]?|DF[1-4])\z/i.freeze
validates :room, presence: true, format: { with: VALID_ROOM_REGEX }, uniqueness: true

def handle_new_date_end_subscription(duration)
time_now = DateTime.now
self.date_end_subscription = if date_end_subscription && (date_end_subscription > time_now)
date_end_subscription + duration.months
else
time_now + duration.months
end
end

def add_subscription(subscription_params)
subscription = subscriptions.new(subscription_params)
if subscription.valid?
handle_new_date_end_subscription(subscription.duration)
save
end
subscription
end

def cancel_subscription(last_subscription)
if subscriptions.count > 1
handle_new_date_end_subscription(-last_subscription.duration)
else
self.date_end_subscription = nil
end
last_subscription.toggle_cancelled
last_subscription.save
save
end

private

def downcase_email
Expand Down
7 changes: 7 additions & 0 deletions app/views/subscriptions/_subscription.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<p>
<%= subscription.id %>,
<%= pluralize(subscription.duration, 'month') %>,
<%= subscription.price %> €,
<%= subscription.updated_at %>,
<%= subscription.cancelled ? "cancelled" : nil %>
</p>
4 changes: 4 additions & 0 deletions app/views/subscriptions/_subscription.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

json.extract! subscription, :id, :duration, :price, :cancelled, :cancelled_date, :created_at, :updated_at
# json.url subscription_url(subscription, format: :json)
5 changes: 5 additions & 0 deletions app/views/subscriptions/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<h1>Subscriptions#index</h1>

<ul>
<%= render @subscriptions %>
</ul>
10 changes: 10 additions & 0 deletions app/views/subscriptions/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<% provide :button_text, "Create" %>

<h1>Subscription#new</h1>

<%= form_with(model: [@user, @subscription], local: true) do |f| %>
<%= render 'utils/error_messages', object: f.object %>
<%= f.label :duration %>
<%= f.text_field :duration, required: true %>
<%= f.submit yield(:button_text) %>
<% end %>
4 changes: 4 additions & 0 deletions app/views/subscriptions/show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# frozen_string_literal: true

json.partial! 'subscriptions/subscription', subscription: @subscription
json.user @subscription.user, partial: 'users/user', as: :user
2 changes: 1 addition & 1 deletion app/views/users/_user.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# frozen_string_literal: true

json.extract! user, :id, :firstname, :lastname, :email, :room, :created_at, :updated_at
json.extract! user, :id, :firstname, :lastname, :date_end_subscription, :email, :room, :created_at, :updated_at
json.url user_url(user, format: :json)
9 changes: 8 additions & 1 deletion app/views/users/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@
<%= @user.lastname %>,
<%= @user.email %>,
<%= @user.room %>,
<%= @user.date_end_subscription %>
</p>
<%= link_to "delete last subscription",user_subscription_url(@user) ,method: :delete %>
<h2>Machines</h2>
<%= link_to "create a new machine", new_user_machine_url(@user) %>
<%= render @user.machines %>
</p>

<h2>Subscriptions</h2>
<%= link_to "add a new subscription", new_user_subscription_url(@user) %>
<%= render @user.subscriptions %>

4 changes: 4 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
Rails.application.routes.draw do
resources :users do
resources :machines, shallow: true
resources :subscriptions, only: %i[new create], shallow: true
delete '/subscriptions', to: 'subscriptions#destroy', as: :subscription
end

get '/subscriptions', to: 'subscriptions#index', as: :subscriptions

# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
12 changes: 12 additions & 0 deletions db/migrate/20210219142026_create_subscriptions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

class CreateSubscriptions < ActiveRecord::Migration[6.0]
def change
create_table :subscriptions do |t|
t.integer :duration, null: false
t.datetime :cancelled_date

t.timestamps
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class AddDateEndSubscriptionToUser < ActiveRecord::Migration[6.0]
def change
add_column :users, :date_end_subscription, :datetime
end
end
7 changes: 7 additions & 0 deletions db/migrate/20210220095330_add_subscriptions_to_users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class AddSubscriptionsToUsers < ActiveRecord::Migration[6.0]
def change
add_reference :subscriptions, :user, foreign_key: true, null: false # rubocop:disable Rails/NotNullColumn
end
end
13 changes: 12 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2020_11_28_153354) do
ActiveRecord::Schema.define(version: 2021_02_20_095330) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand All @@ -34,17 +34,28 @@
t.index ["user_id"], name: "index_machines_on_user_id"
end

create_table "subscriptions", force: :cascade do |t|
t.integer "duration", null: false
t.datetime "cancelled_date"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.bigint "user_id", null: false
t.index ["user_id"], name: "index_subscriptions_on_user_id"
end

create_table "users", force: :cascade do |t|
t.string "firstname", null: false
t.string "lastname", null: false
t.string "email", null: false
t.string "room", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.datetime "date_end_subscription"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["room"], name: "index_users_on_room", unique: true
end

add_foreign_key "ips", "machines"
add_foreign_key "machines", "users"
add_foreign_key "subscriptions", "users"
end
Loading