This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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() | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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"}> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 }); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) { |