Only get published items


I'm new to Ruby and Rails and I'm trying it out with an app that displays artists and their songs. The songs are nested inside the artists. Each song has a "published" and a "approved" attribute that is set to true if the song has been approved and published.

I also have an admin area,

On the frontend I only want to show published and approved items and in the admin area I want to show all songs.

I have created a scope in my model like this:   scope :frontend_songs, where(:approved => true, :published => true)

Which I want to apply on the frontend only. In my songs controller I added a before_filter :front_songs and ...   private

  def front_songs     @songs = @songs.frontend_songs   end

This works good on pages that are not nested inside the artists (like "latest songs")

So I have to do something similar for my Artist controller as well.

Is there a better way to do this so I only have to specify once that songs that has published => false should not be served, regardless if it comes through the artists or songs controller? Like a global scope that always applies except in the admin area.

I have read somewhere about global scopes I think (??) but that you should avoid them. Also, it would break my admin area as well.

So, any ideas?

I would take advantage of arel's method chaining and break down the problem into smaller chunks. Instead of using true scopes, I'd create some useful class methods like so:

class Song < ActiveRecord::Base

  def self.published     where(:published => true)   end

  def self.approved     where(:approved => true)   end


Then in your controllers, call the class methods to match whatever special conditions you need on your song collection (or none at all in, admin's case):

songs_controller: @songs = Song.published.approved

admin_controller: @songs = Song.all

Related reading: