-
Notifications
You must be signed in to change notification settings - Fork 187
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
Store country band details in database #10476
base: main
Are you sure you want to change the base?
Conversation
d02c82a
to
9c50e1a
Compare
91c0294
to
e28d6cc
Compare
lib/dues_calculator.rb
Outdated
country_band = CountryBand.find_by(iso2: country_iso2)&.number | ||
country_band_detail = CountryBandDetail.find_by(number: country_band) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're completely ignoring your new belongs_to
association here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh sorry, changed it.
lib/dues_calculator.rb
Outdated
|
||
[registration_fee_dues_us_dollars, country_band_dues_us_dollars_money].max | ||
# Calculation of 'country band dues' | ||
country_band_dues = Money.new(country_band_detail&.due_amount_per_competitor_in_cents || 0, "USD") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too much happening in one line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cleaned it a bit
lib/dues_calculator.rb
Outdated
# times 100 because Money require lowest currency subunit, which is cents for USD | ||
country_band_dues_us_dollars_money = Money.new(country_band_dues_us_dollars * 100, "USD") | ||
# Calculation of 'registration fee dues' | ||
registration_fee_dues = Money.new(registration_fees * (country_band_detail&.due_percent_registration_fee.to_f || 0) / 100, "USD") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too much happening in one line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cleaned it a bit
app/models/country_band.rb
Outdated
belongs_to :country, foreign_key: :iso2, primary_key: :iso2 | ||
belongs_to :country_band_detail, foreign_key: :number, primary_key: :number |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't fully understand the idea behind this CountryBandDetails
model. It has a start date and an end date, but every CountryBand (which is perpetual/static) contains a column which points it to exactly one CountryBandDetail
.
That means, you could point Band 5 to a CountryBandDetail from 3 years ago, which isn't even valid anymore.
I know you will probably tell me that "WFC will prevent that" but I want to challenge you to see whether you can come up with some better database design first to avoid these problems from happening in the first place
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I didn't think of that case. I've now moved country_band_detail into a function, and I think this is solving the issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or in other words, I'll not have tight coupling between CountryBand and CountryBandDetail, instead CountryBand table will represent the band number of a country (maybe in future we can introduce start_date and end_date as well if we need the history of bands of a country). From the CountryBandDetails table, we can get the active details of a country band.
a47e47d
to
c8162fe
Compare
c8162fe
to
47591c4
Compare
<%= t("country_bands.band_title", number: number) %> | ||
(<%= t("country_bands.due_value", value: data[:value]) %>) | ||
<%= t("country_bands.band_title", number: country_band_detail.number) %> | ||
(<%= t("country_bands.due_value", value: country_band_detail.due_amount_per_competitor_in_cents.to_f / 100) %>) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm 60% sure you don't need the to_f
@@ -0,0 +1,6 @@ | |||
# frozen_string_literal: true | |||
|
|||
class CountryBandDetail < ApplicationRecord |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can specify a belongs_to :country_band
association by providing primary_key: :number
and foreign_key: :number
I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't confuse these with SQL PRIMARY KEY
and FOREIGN KEY
. The options I'm talking about here are (easily misunderstandable) Rails AR vocabulary, which means "the key [i.e. column] where I look up information in the foreign [i.e. pointing to] model, or in myself [i.e. primary]".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh wait, removed it for now. But looks like the association is not used anywhere, is it still needed to have this association here?
app/models/country_band.rb
Outdated
def active_country_band_detail | ||
CountryBandDetail.active.find_by(number: self.number) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As per my other comment in CountryBandDetail
, I think you can solve this via a has_many
relation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
t.integer "number", null: false | ||
t.date "start_date", null: false | ||
t.date "end_date" | ||
t.integer "due_amount_per_competitor_in_cents", null: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe name this column due_amount_per_competitor_us_cents
to make clear that the currency is pre-defined?
|
||
# Calculation of 'registration fee dues' | ||
due_percent_registration_fee = country_band_detail&.due_percent_registration_fee.to_f || 0 | ||
registration_fee_dues = Money.new(registration_fees * due_percent_registration_fee / 100, "USD") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can do calculations with the money object directly:
my_fee = Money.new(2000, "USD")
some_percentage = my_fee * 0.8
registration_fees = Money.new(base_entry_fee_lowest_denomination, currency_code).exchange_to("USD") | ||
|
||
# Calculation of 'registration fee dues' | ||
due_percent_registration_fee = country_band_detail&.due_percent_registration_fee.to_f || 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, I think you don't need the to_f
. Ruby is very flexible with numbers.
belongs_to :country, foreign_key: :iso2, primary_key: :iso2 | ||
validates_inclusion_of :iso2, in: Country::WCA_COUNTRY_ISO_CODES | ||
validates_inclusion_of :number, in: BANDS.keys.freeze |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you hard-code the range from 0 to 5 instead of just completely deleting the line?
I know hard-coding is not very pretty, but effectively it was already hard-coded before (through an intermediate step which was getting the keys from the hard-coded hash)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay done.
spec/models/country_band_spec.rb
Outdated
@@ -15,6 +15,6 @@ | |||
|
|||
it "invalidates band with invalid band id" do | |||
cb = CountryBand.new(number: 6, iso2: "HELLO") | |||
expect(cb).to be_invalid_with_errors(number: ["is not included in the list"]) | |||
expect(cb).to be_invalid_with_errors(country: ["must exist"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding my other comment above, feel free to re-add the previous "number not included in the list" validation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, why did the country
validation that you're testing now not exist/fail before?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added back that error. I just realized the country validation test was already there in the unit test just before this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
belongs_to :country, foreign_key: :iso2, primary_key: :iso2 | ||
validates_inclusion_of :iso2, in: Country::WCA_COUNTRY_ISO_CODES | ||
validates_inclusion_of :number, in: BANDS.keys.freeze |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay done.
@@ -0,0 +1,6 @@ | |||
# frozen_string_literal: true | |||
|
|||
class CountryBandDetail < ApplicationRecord |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay done
app/models/country_band.rb
Outdated
def active_country_band_detail | ||
CountryBandDetail.active.find_by(number: self.number) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -0,0 +1,6 @@ | |||
# frozen_string_literal: true | |||
|
|||
class CountryBandDetail < ApplicationRecord |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh wait, removed it for now. But looks like the association is not used anywhere, is it still needed to have this association here?
spec/models/country_band_spec.rb
Outdated
@@ -15,6 +15,6 @@ | |||
|
|||
it "invalidates band with invalid band id" do | |||
cb = CountryBand.new(number: 6, iso2: "HELLO") | |||
expect(cb).to be_invalid_with_errors(number: ["is not included in the list"]) | |||
expect(cb).to be_invalid_with_errors(country: ["must exist"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added back that error. I just realized the country validation test was already there in the unit test just before this.
This PR aims at removing some hard-coding related to dues details. This will help to make the changes quickly in case we need to make some change in dues in future.