-
Notifications
You must be signed in to change notification settings - Fork 0
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
Users can CRUD deputy assignments #363
Conversation
if deputy.persisted? | ||
existing_deputy_assignment = DeputyAssignment.active.find_by( | ||
primary: primary, | ||
deputy: deputy | ||
) | ||
raise AlreadyAssigned if existing_deputy_assignment.present? | ||
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.
FYI if you are reviewing this commit-by-commit, CodeClimate flagged this and I agree. I moved this check out of this method and into its own in a future commit
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 must admit, I had great difficulty getting through this. I understand there's a lot to get done here, so it's going to be a complicated PR. My main concerns are with the form object which doesn't seem to be sustainably written. In other words, it's going to require a lot of cognitive load when we have to revisit it in the future. Relying on raising and catching exceptions is thornier than using errors
directly. Also, there might some other concerns regarding the PsuIdentity end that could be shoved off to the gem and then it's be one less "branch" condition to deal with here.
I'm happy to pair up or give more detailed feedback, so I'll leave at this for now.
return if active? | ||
return if active_uniqueness_key == id | ||
|
||
update_column(:active_uniqueness_key, id) |
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.
return if active? || active_uniqueness_key == id
?
|
||
# See note at the top of this class for what this does and how. | ||
self.active_uniqueness_key ||= if is_active? | ||
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.
This line is coming up uncovered.
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 noticed that rcov reported this too, even though it is covered
# If we are _creating_ an inactive record, | ||
# init with temp value of current time in millis. | ||
# Will update it to the row's id once we know it | ||
(Time.zone.now.to_f * 1000).to_i |
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 is also uncovered too.
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 noticed that too, except it totally has tests so I don't know what rcov's deal is
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 it's weirded out by some combo of the format/indentation/comments here?
new_user.last_name = psu_identity.family_name | ||
new_user.psu_identity = psu_identity | ||
|
||
raise ErrorCreatingUser unless new_user.valid? |
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.
Why not just add the errors here directly instead of raise/catch?
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 could add errors here, but I still need to raise because I need a way to short-circuit the #save
method if a User cannot be created, i.e. the calling method should not proceed to try to build a DeputyAssignment if the deputy User is invalid and can't be saved.
Now Avdi Grimm claims that you should never use exceptions for control flow and that you should use try / catch
for this purpose instead. The thing is, though, I've never seen anyone actually ever do that. 🤣
errors.add(:base, :identity_service_error) | ||
rescue IdentityNotFound | ||
errors.add(:deputy_webaccess_id, :not_found) | ||
rescue AlreadyAssigned |
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 line isn't covered.
errors.add(:base, :error_creating_user) | ||
rescue StandardError | ||
errors.add(:base, :unknown_error) | ||
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.
Rescuing all the errors strikes me as a bit of a code smell. Could we do the same thing with nil checks, which are faster, and then add the errors as we go?
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 line exists to catch network errors coming from the PsuIdentity gem. Network timeouts, 4xx responses, etc, which could not be handled by nil checks. As best I could tell, that gem does not have a base class for its errors, and right now uses Faraday (which does have a base class). However, that gem could easily not use Faraday in future versions, so it would be foolish to catch Faraday error classes here. If PsuIdentity had its own base class for errors, that's what I'd use on this 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.
No longer uses exceptions for control flow
70d057f
to
4aae43f
Compare
Adam, I refactored that class to not use (as many) catches, give the new version a perusal |
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 2 go.
A few things to note:
deputy_assignments
table, added another column which allows me to write a database level uniqueness constraint that all active DeputyAssignments must have a unique pairing of (primary, deputy) but inactive DeputyAssignments can have multiples. There's now a big comment onDeputyAssignment
class explaining how this works.There is one thing I noticed when coding this up, it seems like the Rails-UJS javascript is being loaded/initialized twice. We should look into that, because any button with
data: { confirm: ... }
will prompt you twice.Closes #269