Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scope for multiple models

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?

like image 399
kidbrax Avatar asked Jan 23 '13 15:01

kidbrax


1 Answers

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.

like image 60
Marc Baumbach Avatar answered Sep 27 '22 19:09

Marc Baumbach