Put Rails scopes nearer to where they're used
Rails scopes are normally put all together near the top of the file, similar to this:
scope :latest, -> { where(retried: [false, nil]) }
scope :retried, -> { where(retried: true) }
scope :ordered, -> { order(:name) }
scope :ordered_by_stage, -> { order(stage_idx: :asc) }
scope :latest_ordered, -> { latest.ordered.includes(project: :namespace) }
scope :retried_ordered, -> { retried.ordered.includes(project: :namespace) }
This has the benefit of being able to view all of them in one place.
This is fine for generic scopes that might be used in many different places. However, for scopes that are predominantly for one feature that is often very far from where they’re used. This greatly reduces readability. You have to jump up and down.
Instead, what I’ve started doing is keeping them closer to where they’re actually used.
scope :latest, -> { where(retried: [false, nil]) }
def update_older_statuses_retried!
self.class
.latest
.where(name: name)
.where.not(id: id)
.update_all(retried: true, processed: true)
end
This greatly improves readability.
The downside is that it might sometimes be difficult to find where it’s defined. However, given that I’d Ctrl+F
for the definition anyways, that hasn’t been a problem so far.
For further development, what I’d like to do is extend the annotate_models
gem to add scopes as well to the top of the file.