Since DHH's keynote at RailsConf there has been a lot of talk about RESTful rails. I finally decided to get up to speed and start exploring. This is a look at the new scaffold_resource and routing that will be in Rails 1.2.
The Rails application is a sort of "jukebox" or more accurately a list of artists and their albums. But enough about the name, let's get started.
and at that point still needed to edit config/routes.rb manually. It looks as if that is taken care of for you now. Pretty cool to see something evolve while you are using it.Last edited by bp (2006-11-02 15:37:59)
Offline
Awesome job with the tutorial! The links at the end are a very nice touch too.
Offline
Nice work, and good links!
bp wrote:
NOTE: Whoa! Default mongrel server. Sweet! (This might have changes a long time ago and I've just noticed. If that's the case please forgive my tardy elatedness.)
Mongrel's been the default in edge rails for at least a couple of months now, but if you don't install it yourself it will revert to lighttpd/webrick.
Offline
Thanks to both of you.
vin wrote:
Mongrel's been the default in edge rails for at least a couple of months now, but if you don't install it yourself it will revert to lighttpd/webrick.
Hehe. I'd gotten so used to just typing 'mongrel_rails start' I didn't even notice. The only reason I used './script/server' here was because I figured people may not have mongrel installed.
Offline
I ran into one problem with this tutorial, which straightened itself out by the end.
The examples provided work perfectly if you're creating your first album for your first artist. In my case, I created two artists, and created one album, attributed to the second artist. But the URL <localhost:3000/artists/2/albums/1> failed, because it wasn't reading the 2 properly. Putting in /artists/1/albums/1 showed the correct album for artist two.
Once I edited my url helpers to include params[:artist_id] and edited the show action to: @albums = Artist.find(params[:artist_id]).albums, then it all cleared up and worked as intended.
I'm not sure if it's worthy of a note in the tutorial itself, because I don't know how many people will go and do something strange like I did!
Offline
jardeon wrote:
The examples provided work perfectly if you're creating your first album for your first artist. In my case, I created two artists, and created one album, attributed to the second artist. But the URL <localhost:3000/artists/2/albums/1> failed, because it wasn't reading the 2 properly. Putting in /artists/1/albums/1 showed the correct album for artist two.
Thanks for pointing this out. I'm not really sure what would cause that. The show method in the albums controller doesn't rely on the artist_id, so in theory, it shouldn't matter what you put there. I get the same album if I hit /artists/12/albums/4 or /artists/2/albums/4. In practice I would probably want to load the artist and the album, so it would matter, but I'm not sure why this happened. Out of curiosity what revision of Rails are you using?
Offline
It's today's revision 5404.
I think I've found the culprit, this is the error I received:
Offline
One of my favorite REST-related articles is Refactoring to REST. I thought I would mention it as I didn't see it in the list of links. Seems the comments have been removed on that post - too bad, some were useful.
Edit: Hmm, seems the link stopped working. Well you can go to scottraymond.net and scroll down.
Last edited by ryanb (2006-11-02 15:35:58)
Offline
ryanb wrote:
One of my favorite REST-related articles is Refactoring to REST. I thought I would mention it as I didn't see it in the list of links. Seems the comments have been removed on that post - too bad, some were useful.
Edit: Hmm, seems the link stopped working. Well you can go to scottraymond.net and scroll down.
Thanks, I forgot to link that one. A great real-world example!
Offline
<b> "Jackpot! We get a listing of albums for artist 1. Too bad the links on this page are now broken. We need to make changes to edit.rhtml, new.rhtml, and show.rhtml just like we did for index.rhtml and include the artist_id in the convenience methods." <b> <br>
I should said great Post, really enjoy it and follow up to understand better Restful Applications with Ruby, however this last step still makes me have a hard time, try to edit edit.rhtml, new.rhtml and show.rhtml but seems to mix the artist_id with the regular id.
Once I create a new album the insert put the record into the DB but the show seems to have confusion in the URL put the :id of the Album instead of the :artist_id
Best Regards Dino.
Offline
# In albums_controller.rb
@albums = Album.find(:all)
Replaced with:
@albums = Artist.find(params[:artist_id]).albums
When add New Album or Edit existing Album show Error on URL putting :id instead of :artist_id.
Generate Error
ActiveRecord::RecordNotFound in AlbumsController#index
Couldn't find Artist with ID=9
The URL Looks Like:
http://192.168.1.36:3000/artists/9/albums
Instead of:
http://192.168.1.36:3000/artists/4/albums [ To show the List of Albums] or
http://192.168.1.36:3000/artists/4/albums/9 [ To display the currently added/edited album ]
On Click Show session dump:
---
flash: !map:ActionController::Flash::FlashHash
:notice: Album was successfully created.
I can tell the new Album or the Edit Album successfully update the DB.
This makes me wonder where after the flash[:notice] my application is being redirected to the wrong URL ???
I wonder if @album = Album.new(params[:id]) need to be changed to something else !!!
Offline
Thanks for the tutorial. I'm still really scratching my head on a few things though...
What is the best way to create a "Administrative" area for your site?? I can't figure this one out. Does it mean I have to put code in every controller just to get an admin layout and views? How do you specify that in the url; the "admin/" part?
What's the point of having a url like /products/32/orders/122? Isn't that a little confusing and this be better: /orders/122? Nested resources don't make sense to me. I can understand using the list view, to show only the related children, but to create, edit or delete seems strange.
Offline
Hope you don't mind if I answer this one bp.
goodieboy wrote:
What is the best way to create a "Administrative" area for your site?? I can't figure this one out. Does it mean I have to put code in every controller just to get an admin layout and views? How do you specify that in the url; the "admin/" part?
Good question. Normally in a RESTful design, there is no special administration section. Instead, user authentication is added and used to determine if a given user is an admin. If he is, he receives special privileges (access to certain actions). You can use simple if conditions in the view to show certain links for the admins. You can then use a before_filter to determine the user going to the given action has the proper access.
For example, if you create an Albums controller and you only want users to access the list/show actions, you can add a before_filter to the create/update/destroy actions to make sure the logged in user is an administrator. If you want a special layout for the admins, you can do this too by passing a symbol to the layout method so it calls another method to determine the layout (see the example in the link).
goodieboy wrote:
What's the point of having a url like /products/32/orders/122? Isn't that a little confusing and this be better: /orders/122? Nested resources don't make sense to me. I can understand using the list view, to show only the related children, but to create, edit or delete seems strange.
Another good question. The only benefit I see is the "/products/32/orders" url where this will show all orders for the given product. Once you get to specifying two ids it gets a little ridiculous IMO. I'm honestly not a fan of nested resources and prefer to just stick with the simple URLs, but other people like them and that's fine with me. 
Offline
OK thanks for that. I get it, it's different than what I'm used to but I'll give it a try.
Another questions here... I've noticed that when you go to a resource/new location... and then post with errors, the errors are missing... because the for actually does a redirect to "create". How do we handle errors from here?? Not sessions? 
Thanks again!
- matt
p.s. I just bought the peep code video and it's really great!.
Offline
Another question!
If you create a named resource route... and you want to redirect to the named route instead of the action name... how is that done?
I've assigned "/login" to the restful_authentication plug-in 'sessions/new' url. But when there is an error, it brings me back to '/sessions' url (it's using redirect_back_or_default).
I just don't want to hard code: "redirect_back_or_default '/login'" into my controller, when that "/Login" reference is being created in routes.rb. Do you know what I mean? Or is that just the way it has to work?
- matt
Offline
goodieboy wrote:
Another questions here... I've noticed that when you go to a resource/new location... and then post with errors, the errors are missing... because the for actually does a redirect to "create". How do we handle errors from here?? Not sessions?
It is common to just render the "new" template instead of redirecting, this way the instance variable containing the validation errors is not lost. You could also use sessions, but this is easier.
goodieboy wrote:
I've assigned "/login" to the restful_authentication plug-in 'sessions/new' url. But when there is an error, it brings me back to '/sessions' url (it's using redirect_back_or_default).
Try placing it above the other map.connect/map.resource definitions in the routes.rb file. When building the URL, the first possible route that passes the conditions is used.
Offline
OK thanks getting somewhere now... but strangely (I'm VERY new to rails and ruby) I can't seem to set an instance variable in the create action, and view it in the new action template. . If I set the instance variable in the new action, the template gets it. How can I set the error for a login (session resource) in the create action, render the new action, and then have the new action template display the error message? The session is not an activerecord model. (but a resource).
- matt
Offline
goodieboy wrote:
OK thanks getting somewhere now... but strangely (I'm VERY new to rails and ruby) I can't seem to set an instance variable in the create action, and view it in the new action template. . If I set the instance variable in the new action, the template gets it. How can I set the error for a login (session resource) in the create action, render the new action, and then have the new action template display the error message? The session is not an activerecord model. (but a resource).
Hmm, I'm not sure what the problem is, the template should have access to any instance variables defined in the action. For example:
Offline