Only get published items

Hi!

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, mysite.com/admin/

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

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:
http://www.railway.at/2010/03/09/named-scopes-are-dead/
http://elabs.se/blog/24-scopes-are-obsolete