Another noob question

Hi!

I'm very new to rails and try to set up a simple app with artists and their songs, for learning.

I have nested routes for some actions to get urls like example.com/ ackord/artistname/songname And I also have some non-nested routes. It looks like this:

  resources :artists, :path => "ackord" do     resources :songs, :path => "", :only => [:index, :edit, :show, :update]   end

  resources :songs, :only => [:new, :create, :destroy]

  match "skicka-in-analys" => "songs#new", :as => :new_song

So far so good!

Now I want to create a list of, say, the 30 latest songs added to my site. I'm trying to be restful and not add new actions, so how do I achieve this? It is a index action but with some extra filters like ...limit(30) and order("created_at DESC") and so on.

This action won't depend on the artist though and therefor shouldn't be nested inside the artists. Since my regular index action IS nested with artists I have all these @artist variables in my view which gives me errors, of course.

So, how do I achieve what I want? Special action or not?

A kick in the right direction would be awesome. I want to learn "the right way" from the beginning.

Best Regards Linus

Now I want to create a list of, say, the 30 latest songs added to my site. I'm trying to be restful and not add new actions, so how do I achieve this? It is a index action but with some extra filters like ...limit(30) and order("created_at DESC") and so on.

Yes, you'll pass in a param (i.e. "/songs/?limit=30") and then use params[:limit] when doing your query. Note that if you plan on using some type of UI front end (say jQuery dataTables) they'll usually have some API for param names they'll send, so if you have no better names to choose from you can just set them to your UI front end so you don't need to translate.

This action won't depend on the artist though and therefor shouldn't be nested inside the artists. Since my regular index action IS nested with artists I have all these @artist variables in my view which gives me errors, of course.

So, how do I achieve what I want? Special action or not?

You should definitely use the index action and not a special action since you're still doing a GET for the collection of songs, which doesn't get more RESTfully pointing to the index action.

The basic premise of what you want to do is wherever you look for songs you need to predicate on params[:artist_id]; if its present you should get and store @artist and then do @artist.songs.all(:condtions => ...), etc.; if its not present then you should do Song.all(:conditions => ...). For rendering it really depends on whether you can have one view that renders a collection of songs (and in the case of artists/5/songs they all happen to be by one artist) or if there is a truely different view you want to render. If its the later, you just predicate your respond_to block on params[:artist_id] as well and render either index_with_artist or index (names up to you of course). If those share a lot of things you can move the common items to partials and then those templates will be calls out to the partials, where the with_artist one renders the artist partial whereas the regular index doesn't.

If you go at all this haphazardly the bookkeeping here can be a bit daunting for all the predication and whatnot, so I'd recommend taking a look at make_resourceful or InheritedResource gems. You can choose to use them or not (they would help you with this problem as well as others), but they both handle optional parents so you can look at their code and what they do to see some good patterns for keeping your code DRY. For example make_resourceful defines something like (in lib/ resourceful/default/accessors.rb):

def current_model   if !parent?     current_model_name.constantize   else     parent_object.send(instance_variable_name)   end end

You should trace down all those function calls, but basically now everywhere you were going to do if params[:artist_id] then @artists.songs.find(...) else Song.find(...), you can now just do current_model.find(...). I'm not as familiar with InheritedResource but both do this similarily in my understanding and both have chosen a good set of utility functions you'd want any controller handling the problem you describe to have.

HTH, \Peter