-
-
Save dcadenas/1902422 to your computer and use it in GitHub Desktop.
Help me clean this up so one scope uses the other!
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
# I have this AR model that has two scopes that should return complementary sets | |
# of rows: one returns all the rows that match certain conditions, the other | |
# returns all rows that DON'T match the same conditions. | |
# | |
# I would like to build the second scope using the first one. Something like: | |
# | |
# class Article | |
# def self.problematic | |
# not(complete) | |
# end | |
# end | |
# | |
# For now the conditions are simple enough (just check for NULL/NOT NULL), but | |
# it's probable that I might need some more complex conditions in the future | |
# (like published_on < Time.current, since our scraper sometimes messes up). | |
# | |
# So this scope will become more complex, and I would like to avoid having to | |
# duplicate all the logic between both scopes. | |
# | |
# After poking around ARel's source code for a while I didn't find an easy way | |
# to do this. How would you approach this? | |
class Article < ActiveRecord::Base | |
@attributes_required_for_complete = [:published_on, :title, :text, :url] | |
# Public: Filter out articles that don't have all the information required for | |
# us to show to users. | |
# | |
# Returns an ActiveRecord::Relation. | |
def self.complete | |
@attributes_required_for_complete.inject(self) do |relation, field| | |
relation.where("#{field} IS NOT NULL") | |
end | |
end | |
# Public: Filter articles that don't have all the information required for us | |
# to show to users. This returns the complement of Article.complete. | |
# | |
# Returns an ActiveRecord::Relation. | |
def self.problematic | |
conditions = @attributes_required_for_complete.map do |field| | |
arel_table[field].eq(nil) | |
end | |
where(conditions.inject(:or)) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment