Skip to content

Instantly share code, notes, and snippets.

View bjudson's full-sized avatar
🧐

Ben Judson bjudson

🧐
View GitHub Profile
"""
Context:
The following code defines two Django models with a many-to-many through relationship, where each
of the three models (including the join model) inherit from a SoftDeletionModel with a custom manager
that uses get_queryset to transparently filter out the soft-deleted objects.
Problem:
If we have a Title instance with a Contributor, then call `title.contributors.remove(contributor)`,
this will set the `deleted_at` field of the TitleContributor join instance. Now, if we call
`title.contributors.count()` we will get 1, but `title.titlecontributor_set.count()` will return 0.
@bjudson
bjudson / soft_deletion.py
Created October 12, 2021 17:37
Django soft deletion model mixin
class SoftDeletionQuerySet(models.QuerySet):
def delete(self):
"Set deleted_at, and call delete() on related cascade models"
cascade_fields = self.model.get_cascade_fields()
for field in cascade_fields:
# NOTE: this works for the common use case, but is not fully generalized.
# eg if there are multiple joining columns, this will not work as expected
# so in that situation, we're just going to bail out rather than risk
# an incorrect delete
join_cols = field.get_joining_columns()
/**
* Stores a generic promise for resolution based on external factors.
*
* Useful when you want to create a promise as a kind of bridge between two
* events that don't naturally create a promise.
*/
/**
* Wraps generic promise in order to expose resolve() & reject()
*/
/**
* Allows user to copy something to the clipboard by clicking an element (typically a link or
* button).
*
* This componenet uses "render prop" approach. If props.payload is defined, this component handles
* rendering a hidden input internally (using payload as value), but anything else should be
* rendered within a function passed in as props.children (aka render prop). The element that the
* user clicks to copy the payload needs to use targetProps.
*
* <CopyToClipboard payload={"some text to copy"}>
@bjudson
bjudson / errorBoundary.jsx
Created December 29, 2017 22:37
React error boundary component with Sentry feedback
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
componentDidCatch(error, info) {
this.setState({ hasError: true });
Raven.captureException(error, { extra: info });
}
@bjudson
bjudson / raven-middleware.js
Last active April 18, 2018 07:43
raven for redux middleware config
import createRavenMiddleware from "raven-for-redux";
export default createRavenMiddleware(window.Raven, {
stateTransformer: function(state) {
return Object.assign({}, state, {
entities: flattenEntities(state.entities)
});
},
actionTransformer: function(action) {
if (action.response && action.response.entities) {