Skip to content

Commit d9e2dac

Browse files
committed
messy solution - 15 Files Changed
1 parent 7ca6d82 commit d9e2dac

15 files changed

+150
-30
lines changed

app/apis/currency_helper.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
class CurrencyHelper
44
class << self
55
def find_currency(user)
6-
case user.person.address.country
6+
case user.person.address.on(Date.today).country
77
when 'CH'
88
'CHF'
99
when 'DE'

app/controllers/accounting_controller.rb

+6-4
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22

33
class AccountingController < ApplicationController
44
def show(*)
5-
holdings = Security.joins(user: { person: :address })
6-
.group('addresses.country', 'securities.ticker')
7-
.sum('securities.quantity')
5+
holdings =
6+
Security.joins(user: { person: { address: :address_versions } })
7+
.group('address_versions.country', 'securities.ticker')
8+
.sum('securities.quantity')
89

910
evaluated_holdings = holdings.map do |(country, ticker), quantity|
1011
fee_dollar = StockApi.get_share_price(ticker, Date.today) * quantity * Constants::FEE_RATE
1112

12-
user = Address.find_by(country:).person.user
13+
address_version = AddressVersion.on_date(Date.today).where(country:).first
14+
user = address_version.address.person.user
1315
currency = CurrencyHelper.find_currency(user)
1416
rate = CurrencyExchangeApi.find_conversion_rate('USD', currency, Date.today)
1517
fee_currency = fee_dollar * rate

app/controllers/login_controller.rb

+20-3
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,15 @@ def login(email:, password:)
1616
end
1717

1818
def signup(email:, password:, passcode:, name:, street:, zip:, city:, country:) # rubocop:disable Metrics/ParameterLists
19-
address = Address.new(street:, city:, zip:, country:)
20-
person = Person.new(name:, address:)
21-
@user = User.new(email:, password:, person:)
19+
# address = Address.create
20+
# address.address_versions.create(
21+
# street:, city:, zip:, country:, valid_from: Time.now
22+
# )
23+
# person = Person.create(address:)
24+
# person.name_versions.create(name:, valid_from: Time.now)
25+
26+
# @user = User.new(email:, password:, person:)
27+
@user = build_user(email:, password:, name:, street:, zip:, city:, country:) # rubocop:disable Metrics/LineLength
2228

2329
if passcode.present?
2430
passcode = Passcode.find_by(name:, street:, zip:, city:, country:, passcode: passcode.to_i)
@@ -42,6 +48,17 @@ def show_profile(user_id:)
4248

4349
private
4450

51+
def build_user(email:, password:, name:, street:, zip:, city:, country:) # rubocop:disable Metrics/ParameterLists
52+
address = Address.create
53+
address.address_versions.create(
54+
street:, city:, zip:, country:, valid_from: Date.today
55+
)
56+
person = Person.create(address:)
57+
person.name_versions.create(name:, valid_from: Date.today)
58+
59+
User.new(email:, password:, person:)
60+
end
61+
4562
def redirect(_user)
4663
if @user.admin?
4764
redirect_to(AdminController, user_id: @user.id)

app/controllers/profile_controller.rb

+7-8
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,19 @@ def show(user_id:)
1010
def change_name_to(user_id:, name:, valid_from:)
1111
@user = User.find(user_id)
1212

13-
@user.person.name = name
14-
@user.save
13+
NameVersion.create(
14+
person_id: @user.person.id, name:, valid_from:
15+
)
1516

1617
render(ProfileView)
1718
end
1819

1920
def change_address_to(user_id:, street:, zip:, city:, country:, valid_from:)
2021
@user = User.find(user_id)
21-
22-
@user.person.address.street = street
23-
@user.person.address.zip = zip
24-
@user.person.address.city = city
25-
@user.person.address.country = country
26-
@user.save
22+
AddressVersion.create(
23+
address_id: @user.person.address.id,
24+
street:, zip:, city:, country:, valid_from:
25+
)
2726

2827
render(ProfileView)
2928
end

app/models/address.rb

+9
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,13 @@
22

33
class Address < ActiveRecord::Base
44
has_one :person
5+
has_many :address_versions
6+
7+
def last
8+
address_versions.order(valid_from: :desc).first
9+
end
10+
11+
def on(date = Date.today)
12+
address_versions.where('valid_from <= ?', date).order(valid_from: :desc).first
13+
end
514
end

app/models/address_version.rb

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# frozen_string_literal: true
2+
3+
class AddressVersion < ActiveRecord::Base
4+
belongs_to :address
5+
6+
scope :on_date, lambda { |date|
7+
where('valid_from <= ?', date)
8+
.order(valid_from: :desc)
9+
.limit(1)
10+
}
11+
end

app/models/name_version.rb

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# frozen_string_literal: true
2+
3+
class NameVersion < ActiveRecord::Base
4+
belongs_to :person
5+
end

app/models/person.rb

+19
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,23 @@
33
class Person < ActiveRecord::Base
44
belongs_to :address, autosave: true
55
has_one :user
6+
has_many :name_versions
7+
8+
def version_dates
9+
(
10+
name_versions.map(&:valid_from) +
11+
address.address_versions.map(&:valid_from)
12+
).sort.uniq
13+
end
14+
15+
def name
16+
name_versions.order(valid_from: :desc)
17+
.first&.name
18+
end
19+
20+
def name_on(date = Date.today)
21+
name_versions.where('valid_from <= ?', date)
22+
.order(valid_from: :desc)
23+
.first&.name
24+
end
625
end

app/views/admin_view.rb

+10-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,16 @@ def title = 'Administrator dashboard'
66

77
def content
88
@users.select { _1.person.present? }.map do |user|
9-
"#{user.email}, #{user.person.name}, #{user.person.address.street}, #{user.person.address.zip} #{user.person.address.city}, #{user.person.address.country}"
9+
person = user.person
10+
version_dates = person.version_dates
11+
(
12+
["#{user.email}:"] +
13+
version_dates.map do |date|
14+
name = person.name_on(date)
15+
address = person.address.on(date)
16+
" #{name}, #{address.street}, #{address.zip} #{address.city}, #{address.country}"
17+
end
18+
).join("\n")
1019
end.join("\n")
1120
end
1221

app/views/investment_fees_view.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# frozen_string_literal: true
22

33
class InvestmentFeesView < View
4-
def title = "#{@user.person.name}'s fees (in #{currency})"
4+
def title = "#{@user.person.name_on(Date.today)}'s fees (in #{currency})"
55

66
def content
77
if @fees.positive?

app/views/investment_news_view.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# frozen_string_literal: true
22

33
class InvestmentNewsView < View
4-
def title = "#{@user.person.name}'s news"
4+
def title = "#{@user.person.name_on(Date.today)}'s news"
55

66
def content = @news
77
end

app/views/portfolio_view.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ def title = "#{@user.person.name}'s portfolio"
77
def content
88
currency = CurrencyHelper.find_currency(@user)
99
if @portfolio_value.positive?
10-
"#{@user.person.name}, your portfolio is worth #{format('%.2f', @portfolio_value)} #{currency}"
10+
"#{@user.person.name_on(Date.today)}, your portfolio is worth #{format('%.2f', @portfolio_value)} #{currency}"
1111
else
12-
"#{@user.person.name}, your portfolio is worth nothing"
12+
"#{@user.person.name_on(Date.today)}, your portfolio is worth nothing"
1313
end
1414
end
1515

app/views/profile_view.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# frozen_string_literal: true
22

33
class ProfileView < View
4-
def title = "#{@user.person.name}'s profile"
4+
def title = "#{@user.person.name_on(Date.today)}'s profile"
55

66
def content
77
person = @user.person
8-
address = person.address
8+
address = person.address.on(Date.today)
99
<<~PROFILE
10-
Name: #{person.name}
10+
Name: #{person.name_on(Date.today)}
1111
EMail: #{@user.email}
1212
Address: #{address.street}, #{address.zip} #{address.city}
1313
Country: #{address.country}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# frozen_string_literal: true
2+
3+
class CreateVersions < ActiveRecord::Migration[7.0]
4+
def change
5+
create_table :address_versions do |t|
6+
t.references :address, null: false, foreign_key: true
7+
t.string :street
8+
t.string :city
9+
t.string :zip
10+
t.string :country
11+
t.date :valid_from, null: false
12+
13+
t.timestamps
14+
end
15+
16+
create_table :name_versions do |t|
17+
t.references :person, null: false, foreign_key: true
18+
t.string :name
19+
t.date :valid_from, null: false
20+
21+
t.timestamps
22+
end
23+
24+
remove_column :people, :name, :string
25+
26+
remove_column :addresses, :street, :string
27+
remove_column :addresses, :city, :string
28+
remove_column :addresses, :zip, :string
29+
remove_column :addresses, :country, :string
30+
end
31+
end

db/schema.rb

+24-6
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,29 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema[7.0].define(version: 2023_09_15_080533) do
13+
ActiveRecord::Schema[7.0].define(version: 2023_10_14_080533) do
14+
create_table "address_versions", force: :cascade do |t|
15+
t.integer "address_id", null: false
16+
t.string "street"
17+
t.string "city"
18+
t.string "zip"
19+
t.string "country"
20+
t.date "valid_from", null: false
21+
t.datetime "created_at", null: false
22+
t.datetime "updated_at", null: false
23+
t.index ["address_id"], name: "index_address_versions_on_address_id"
24+
end
25+
1426
create_table "addresses", force: :cascade do |t|
15-
t.string "street", null: false
16-
t.string "city", null: false
17-
t.string "zip", null: false
18-
t.string "country", null: false
27+
end
28+
29+
create_table "name_versions", force: :cascade do |t|
30+
t.integer "person_id", null: false
31+
t.string "name"
32+
t.date "valid_from", null: false
33+
t.datetime "created_at", null: false
34+
t.datetime "updated_at", null: false
35+
t.index ["person_id"], name: "index_name_versions_on_person_id"
1936
end
2037

2138
create_table "passcodes", force: :cascade do |t|
@@ -28,7 +45,6 @@
2845
end
2946

3047
create_table "people", force: :cascade do |t|
31-
t.string "name", null: false
3248
t.integer "address_id", null: false
3349
t.index ["address_id"], name: "index_people_on_address_id"
3450
end
@@ -48,6 +64,8 @@
4864
t.index ["person_id"], name: "index_users_on_person_id"
4965
end
5066

67+
add_foreign_key "address_versions", "addresses"
68+
add_foreign_key "name_versions", "people"
5169
add_foreign_key "people", "addresses"
5270
add_foreign_key "securities", "users"
5371
add_foreign_key "users", "people"

0 commit comments

Comments
 (0)