I have several objects that all have an approved field. 
What would be the best way to implement a scope to use across all models?
For example, I have a sighting object and a comment object. They both have to be approved by an admin before being availalbe to the public. 
So how can I create a scope that returns comment.approved as well as sighting.approved respectively without repeating it on each model?  Is this where concerns comes into play?
While just declaring a scope in each model is fine if you just want the scoping functionality. Using an ActiveSupport::Concern will give you the ability to add additional methods as well if that's something you think is going to happen. Here's an example:
# /app/models/concerns/approved.rb
module Approved
  extend ActiveSupport::Concern
  included do
    default_scope { where(approved: false) }
    scope :approved, -> { where(approved: true) }
  end
  def unapprove
    update_attribute :approved, false
  end
end
class Sighting < ActiveRecord::Base
  include Approved
end
class Comment < ActiveRecord::Base
  include Approved
end
Then you can make calls like Sighting.approved and Comment.approved to get the appropriate list of approved records. You also get the unapprove method and can do something like Comment.approved.first.unapprove.
In this example, I've also included default_scope which will mean that calls like Sighting.all or Comment.all will return only unapproved items. I included this just as an example, it may not be applicable to your implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With