-
Notifications
You must be signed in to change notification settings - Fork 35
WIP: Move states into separate tables #1494
base: develop
Are you sure you want to change the base?
Conversation
@@ -71,8 +86,12 @@ def auction_rejected? | |||
parsed_attributes[:status] == 'rejected' | |||
end | |||
|
|||
def parser |
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.
Just noticed I need to be smarter about the memoization. I could fix this by memoizing attributes
when AuctionParser
is instantiated.
@@ -1,6 +1,8 @@ | |||
db: | |||
image: postgres:9 | |||
web: | |||
tty: true |
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.
Useful for pry
ing in using docker-compose
and docker attach
.
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.
Good start. I wrote lots of comments on the testing, and a few other places.
app/models/auction.rb
Outdated
@@ -8,6 +8,7 @@ class Auction < ActiveRecord::Base | |||
belongs_to :customer | |||
has_many :bids | |||
has_many :bidders, through: :bids | |||
has_many :states, foreign_key: 'auction_id', class_name: 'AuctionState' |
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.
Do you need the foreign_key
? I thought you only needed to specify that if it went against convention, like with the class_name
in this case.
app/models/auction_parser.rb
Outdated
private | ||
|
||
def changing?(key, value) |
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.
This additional abstraction is confusing to me. What is it for?
create_published_state | ||
# add more state creation here, as needed | ||
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.
This I get!
spec/models/auction_parser_spec.rb
Outdated
publishing = parser.publishing? | ||
|
||
expect(publishing).to be true | ||
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.
You are going to want to test the opposite too, when not publishing to make sure that works.
spec/services/update_auction_spec.rb
Outdated
# do we want to low-level test for the published state object, like this? | ||
published_state = auction.states.find {|state| state.name == 'published'} | ||
expect(published_state.state_value).to eq('published') | ||
|
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.
^^^ that seems like the important part to test. You should probably also test what happens when an auction moves from 'archived' to 'published' in that case it will already have a record, so changing the count of records should not happen.
I forgot to mention that you can put a constraint in the database on that not happening by adding a uniq index on ['auction_id', 'name']
. Then if a unique index error is thrown you revert back to updating. Solves some obscure bugs that Rails generates via their expectation that there is always just one server running in one thread.
spec/services/update_auction_spec.rb
Outdated
expect(published_state.state_value).to eq('published') | ||
|
||
# and/or this?: | ||
# expect(auction.published?).to be true |
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.
This doesn't seem important to me. It seems like that is the interface expansion that I was complaining about. Special methods for states instead of just setting state and reading state. Since the states are distributed now, we will need a nice way to read states. auction.state_for('published') # "archived"
???
spec/services/update_auction_spec.rb
Outdated
# and/or this?: | ||
# published = AuctionPublishedState.new(auction).perform | ||
# expect(published).to be true | ||
|
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 would only test this as the return value if you already had plans to use it somewhere. Otherwise the maintenance is overhead.
spec/services/update_auction_spec.rb
Outdated
# and/or this?: | ||
# published = FindAuctionState.new(auction, name: 'published').perform | ||
# expect(published).to be true | ||
|
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.
Future class? I don't have a problem with a separate object for getting state ... probably good. But we are going to need an easy way to read state from an auction that is less wordy.
An idea for a state builder: ChangeState.new(auction, published: :unpublished).perform Although maybe raw ActiveRecord is still fine. The abstractions don't seem to abstract too much other than the column names of UPDATEEnded up writing something close: ChangeState.new(auction, 'published', 'unpublished').perform This helps simplify |
af347c8
to
8870f1f
Compare
end | ||
|
||
private | ||
|
||
attr_reader :auction, :params, :current_user | ||
|
||
def create_auction_states | ||
create_published_state |
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.
Let's consider changing the published state name to something like visibility
.
So far: - created auction_states migration - added hook into UpdateAuction to create_auction_states - create auction state when publishing an auction - test that UpdateAuction creates an AuctionStatus when publishing
In doing so, also: - swept ArchiveAuction into UpdateAuction (so all updates pass through it and no forked behavior in the controller) - added AuctionParser#archiving? - added tests to UpdateAuction to test for archiving and to ensure published isn't inappropriately set
8870f1f
to
601e0b3
Compare
CreateAuction makes it easier to implement and test calls to ChangeState. In CreateAuction we will make explicit an previously implicit state: 'unpublished'. unpublished is the default published state for auctions thanks to a default call in a migration. But we will also ensure that any newly-created auctions also get a State object created reflecting this state.
bab91c5
to
2d7ed6a
Compare
This implementation isn't perfect. There's some trickness in figuring out the order of building and saving auctions and their child objects, states. ActiveRecord doesn't make this very clean to paper over. Rather than have overly-complex persistence-management logic, I'm naively sending potentially extra #save calls to the db.
Working with @baccigalupi to pay down some technical debt by moving many of the groupings of fields on
Auction
into their own state objects. The disambiguation will make the code easier to reason about, and easier to modify as state needs change.