From 727372c7ef0d2bceabfeb776e4f6d3453ae81048 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Tue, 16 Feb 2016 15:00:43 +0100 Subject: [PATCH 1/4] implement frecency --- app/controllers/orders_controller.rb | 2 +- app/models/order.rb | 7 +++++++ app/models/user.rb | 8 ++++++++ config/application.rb | 1 + db/migrate/20160216133104_add_frecency_to_users.rb | 5 +++++ db/schema.rb | 3 ++- 6 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20160216133104_add_frecency_to_users.rb diff --git a/app/controllers/orders_controller.rb b/app/controllers/orders_controller.rb index c863a32..e93eff2 100644 --- a/app/controllers/orders_controller.rb +++ b/app/controllers/orders_controller.rb @@ -26,7 +26,7 @@ class OrdersController < ApplicationController end def overview - @users = User.members.publik.order(:name) + @users = User.members.publik.order(:frecency, :desc) @last = Order.order(:created_at).reverse_order.includes(:user).limit(10).map(&:user) end diff --git a/app/models/order.rb b/app/models/order.rb index b8379b8..a5276c9 100644 --- a/app/models/order.rb +++ b/app/models/order.rb @@ -21,6 +21,9 @@ class Order < ActiveRecord::Base before_save { |o| o.order_items = o.order_items.reject{ |oi| oi.count == 0 } } after_create :create_api_job, unless: -> { user.guest? } + after_create :update_user_frecency + after_destroy :update_user_frecency + validates :user, presence: true validates_associated :order_items validate :product_presence @@ -66,4 +69,8 @@ class Order < ActiveRecord::Base def product_presence errors.add(:base, "You have to order at least one product.") if order_items.map(&:count).sum.zero? end + + def update_user_frecency + self.user.calculate_frecency + end end diff --git a/app/models/user.rb b/app/models/user.rb index af1ab09..f112993 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -41,6 +41,14 @@ class User < ActiveRecord::Base end end + def calculate_frecency + num_orders = Rails.application.config.frecency_num_orders + last_timestamps = self.orders.order(created_at: :desc) + .limit(num_orders) + .pluck(:created_at) + self.frecency = last_timestamps.map(&:to_i).sum / num_orders + end + def balance @balance || begin headers = { diff --git a/config/application.rb b/config/application.rb index 440e031..ab81a82 100644 --- a/config/application.rb +++ b/config/application.rb @@ -22,5 +22,6 @@ module Tab002 config.active_record.raise_in_transactional_callbacks = true config.active_job.queue_adapter = :delayed_job config.call_api_after = 5.minutes + config.frecency_num_orders = 10 end end diff --git a/db/migrate/20160216133104_add_frecency_to_users.rb b/db/migrate/20160216133104_add_frecency_to_users.rb new file mode 100644 index 0000000..66e377d --- /dev/null +++ b/db/migrate/20160216133104_add_frecency_to_users.rb @@ -0,0 +1,5 @@ +class AddFrecencyToUsers < ActiveRecord::Migration + def change + add_column :users, :frecency, :integer, default: 0, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 9b20310..e3d3c0e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160202133903) do +ActiveRecord::Schema.define(version: 20160216133104) do create_table "barcodes", force: :cascade do |t| t.integer "product_id" @@ -85,6 +85,7 @@ ActiveRecord::Schema.define(version: 20160202133903) do t.boolean "koelkast", default: false t.string "name" t.boolean "private", default: false + t.integer "frecency", default: 0, null: false end add_index "users", ["koelkast"], name: "index_users_on_koelkast" From 3b4784727697a2db7db18d00b9eab71928983aaf Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Tue, 16 Feb 2016 15:03:15 +0100 Subject: [PATCH 2/4] also save the model after changing it ... --- app/models/user.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/user.rb b/app/models/user.rb index f112993..1d17b60 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -47,6 +47,7 @@ class User < ActiveRecord::Base .limit(num_orders) .pluck(:created_at) self.frecency = last_timestamps.map(&:to_i).sum / num_orders + self.save end def balance From b5970738b9dd9da0abd1a00f6492dc5e521bce91 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Tue, 16 Feb 2016 15:04:49 +0100 Subject: [PATCH 3/4] I cannot into rails --- app/controllers/orders_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/orders_controller.rb b/app/controllers/orders_controller.rb index e93eff2..6589a89 100644 --- a/app/controllers/orders_controller.rb +++ b/app/controllers/orders_controller.rb @@ -26,7 +26,7 @@ class OrdersController < ApplicationController end def overview - @users = User.members.publik.order(:frecency, :desc) + @users = User.members.publik.order(frecency: :desc) @last = Order.order(:created_at).reverse_order.includes(:user).limit(10).map(&:user) end From c6dc220d3d477714113a458a3b0e462397321de1 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Tue, 16 Feb 2016 15:38:44 +0100 Subject: [PATCH 4/4] fix formula and test it --- app/models/user.rb | 8 ++++---- spec/models/user_spec.rb | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 1d17b60..3045c69 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -43,10 +43,10 @@ class User < ActiveRecord::Base def calculate_frecency num_orders = Rails.application.config.frecency_num_orders - last_timestamps = self.orders.order(created_at: :desc) - .limit(num_orders) - .pluck(:created_at) - self.frecency = last_timestamps.map(&:to_i).sum / num_orders + last_datetimes = self.orders.order(created_at: :desc) + .limit(num_orders) + .pluck(:created_at) + self.frecency = last_datetimes.map(&:to_time).map(&:to_i).sum / num_orders self.save end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 7aab751..f21a132 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -133,4 +133,23 @@ describe User do expect(User.publik).to eq([@user, user]) end end + + describe 'frecency' do + it 'should be recalculated on creating an order' do + expect(@user.frecency).to eq 0 + create :order, user: @user + expect(@user.frecency).to_not eq 0 + end + + it 'should be valid' do + dates = [Date.today.to_time, Date.yesterday.to_time] + dates.each do |date| + create :order, user: @user, created_at: date + end + @user.reload + num_orders = Rails.application.config.frecency_num_orders + frecency = dates.last(num_orders).map(&:to_i).sum/num_orders + expect(@user.frecency).to eq(frecency) + end + end end