You made a grave faux pas by not sanitising (html_escape, h) the search parameter when displaying it into the textbox after the seach; this is an avenue for XSS attacks.
What about showing how to search by booleans like 'AND', 'OR', etc.. or is that too complex to show in these casts?
Or what about doing an example that shows how exactly to get timezones setup and show some examples of using them? I found some good examples online but a screencast might be better.
How about adding some ajax stuff such as a dynamicly generated drop-down box for the search field showing contents of a dictionary or project names based on the entered substring?
And PLEASE tell us something about deployment. A sample lighty or mongrel based setup would be nice. Thanks a lot for the excellent screencasts!
@Zubin, right, it has to be a :member to pass "id". The reason being is "id" should represent one task (or whatever the resource is). It should be unique to that task.
You could fall back on the standard route, but this is going away from REST.
@Michael, you would supply it in the same :collection hash, no need to specify it twice.
This was a great railscast. There is one thing, however, that I'd recommend with screencasts of this nature. Expand on the existing theme. For instance give us information on what we need to do if we have more than one action to add of a certain type:
Thanks Ryan, I presume you mean it has to be a :member in order to pass the :id?
Any reason not to fall back on standard routes? So the path would look like this: /products/tagged/interesting (calls "tagged" method in listings_controller).
@Zubin, a "collection" route doesn't accept an :id parameter. It is only for predefined collections. You can still pass the name/id of a tag and search based off of that, but it will show up at the end of the url:
/products;tagged?tag=interesting
If you don't want this behavior you'll have to create a custom route outside of REST - or display the products from inside the tags show page.
Good question. It's not necessary because it continues as normal if it returns nil (which it will if the condition isn't met). The only time it stops is if it returns false.
Great screencast Ryan! I've been meaning to use subversion though I mostly just wanted to 'jump right in' to Rails. Now I don't have an excuse to not use it!
@Rebort, I generally keep it on a remote server, but I setup subversion on my local for testing purposes. If you want to deploy the project it's pretty necessary to host it remotely so the web server can access the repository.
Great video, Ryan. I'm hoping there's more in the works on subversion. (I've read a few "get started with" tutorials -- but the odd thing is _none_ of them cover how to roll back changes and checkout older versions of your app).
One last question: Where do most folks keep their repository? Locally or on a remote server? It makes more sense to me to keep everything off your local box, but I'm not sure if this is the way it is "supposed" to be done.
This website is definitely the best Rails ressource on the web. Thank you for your railscasts. I've been watching them for a while and they keep getting better and better.
For those that want to automate the ignores and stuff, I've been happy with the configure_for_svn rake task @ http://snippets.dzone.com/tag/configure_for_svn (just make sure you read all that that task does before using it. I tweak my copy a smidge).
I thing you have forgotten a crucial step in this chapter, it's about setting up svn:executable in the script/ directory and the dispath.* files. This is very important when you are using different machines, Windows workstation for dev and test and Linux server for production. Not everybody uses MacOSX and TextMate (I do, but I have had to work with Windows + RadRails in the past).
Perhaps you might let it to a chapter about deploying rails apps in remote machines, but I miss that in this chapter because it covers all the steps I do when I start a rails app, except that point.
My congratulations for your contribution and your excelent screencasts. You are worthy of generous donations for this.
Another great screencast. I had one question, though. Is the determination of the plurality of the link generation method (i.e. action_task_path vs action_tasks_path) made by whether you've added it to the collection hash vs. the member hash in the routes.rb file?
Thats great practical information on REST. I think it should be noted that you dont need to create a new model if you want to make those actions RESTful.
If you find yourself creating CRUD like actions to manage your "completed" column. Create only a new (RESTful) controller. This has often worked well for me.
@Manuel, I hear you. I wasn't convinced of REST initially either. I don't think it's possible to convince someone, it's just something you need to try for yourself. Then compare the code before/after - that's what convinced me.
Ironically as it may sound, the biggest benefit of REST is the limitations it brings. It's what keeps your code clean and design normalized.
@Ralph,
Zubin is correct. Also, if you want to learn more, you should buy Peepcode's RESTful tutorial. It's $9, 85 minutes long, and comes with all the source code. It's an excellent resource for REST!
Thanks for this great screencast! However I'm still not convinced about REST. It's to limiting without bringing too much benefit I think. Maybe in the future...
I've always wondered if I can use custom identifiers for members. For example, I have an articles controller. The show action needs the id of the article, so I have urls like /articles/1. But I want urls like /articles/some-article-title. Is this possible somehow?
Very cool. But when I try to install from Textmate I get this:
/Applications/TextMate.app/Contents/SharedSupport/Bundles/Rails.tmbundle/Support/lib/rails/text_mate.rb:69:in `method_missing': undefined method `filepath' for TextMate:Module (NoMethodError) from /Applications/TextMate.app/Contents/SharedSupport/Bundles/Rails.tmbundle/Support/lib/rails/rails_path.rb:43:in `initialize' from /Applications/TextMate.app/Contents/SharedSupport/Bundles/Rails.tmbundle/Support/bin/list_plugins.rb:25
Opensource error messages are truly in a world of their own...
For some reason I get a NameError whenever I try to use path but url works great. Is there any reason to believe that path is deprecated or replaced with something else? Or is there something else we need to set somewhere for this to work right?
@Lisa: Rails is doing that automatically.
You made a grave faux pas by not sanitising (html_escape, h) the search parameter when displaying it into the textbox after the seach; this is an avenue for XSS attacks.
What about showing how to search by booleans like 'AND', 'OR', etc.. or is that too complex to show in these casts?
Or what about doing an example that shows how exactly to get timezones setup and show some examples of using them? I found some good examples online but a screencast might be better.
How about adding some ajax stuff such as a dynamicly generated drop-down box for the search field showing contents of a dictionary or project names based on the entered substring?
And PLEASE tell us something about deployment. A sample lighty or mongrel based setup would be nice. Thanks a lot for the excellent screencasts!
Nice, but what about more complicated non-model forms with many fields with validation required?
Thanks Ryan, another great episode, much appreciated!
@Zubin, right, it has to be a :member to pass "id". The reason being is "id" should represent one task (or whatever the resource is). It should be unique to that task.
You could fall back on the standard route, but this is going away from REST.
@Michael, you would supply it in the same :collection hash, no need to specify it twice.
:collection => { :recent => :get, :completed => :get }
This was a great railscast. There is one thing, however, that I'd recommend with screencasts of this nature. Expand on the existing theme. For instance give us information on what we need to do if we have more than one action to add of a certain type:
map. resources :items, :collection => {:recent => :get}
. . .how do I add more than one? Do I need another "collection" declaration or can I put each one inside the same set of brackets?
As these screencasts are already amazing, expounding in this manner would be priceless.
Thanks!
another resource: http://railswatcher.com/past/2007/3/15/putting_rails_on_svn/
Thanks Ryan, I presume you mean it has to be a :member in order to pass the :id?
Any reason not to fall back on standard routes? So the path would look like this: /products/tagged/interesting (calls "tagged" method in listings_controller).
@Zubin, a "collection" route doesn't accept an :id parameter. It is only for predefined collections. You can still pass the name/id of a tag and search based off of that, but it will show up at the end of the url:
/products;tagged?tag=interesting
If you don't want this behavior you'll have to create a custom route outside of REST - or display the products from inside the tags show page.
Good question. It's not necessary because it continues as normal if it returns nil (which it will if the condition isn't met). The only time it stops is if it returns false.
I'm a little confused about collections in named routes. Can you pass a parameter to define the collection?
eg /products/tagged/interesting
from map.resources.products, :collection => {:tagged => :get}
but where would :id (tag) go? Or is this not possible using REST?
Doesn't the before_filter need to return true in the other case in order to normally proceed the request?
tss.. i'm mistake writing the post, .."is the bes postcast of rails..." sorry jajajaja...
wow, great!... congratulations ryan, is the best podcast of ruby ;), simple and short.
good luck ;)
Great screencast Ryan! I've been meaning to use subversion though I mostly just wanted to 'jump right in' to Rails. Now I don't have an excuse to not use it!
Nice work once again Ryan. I second the idea of a rake script to handle this. Rake scripts are very under–rated.
@Rebort, I generally keep it on a remote server, but I setup subversion on my local for testing purposes. If you want to deploy the project it's pretty necessary to host it remotely so the web server can access the repository.
A good source for the svn steps is
http://blog.teksol.info/articles/2006/03/09/subversion-primer-for-rails-projects
Great video, Ryan. I'm hoping there's more in the works on subversion. (I've read a few "get started with" tutorials -- but the odd thing is _none_ of them cover how to roll back changes and checkout older versions of your app).
One last question: Where do most folks keep their repository? Locally or on a remote server? It makes more sense to me to keep everything off your local box, but I'm not sure if this is the way it is "supposed" to be done.
Thanks again for all your hard work!
As usual, another helpful screencast. Maybe you could have one about Capistrano to complement Subversion? Great work as always, Ryan.
@Markús, thanks for pointing that out. I didn't know about this step.
This website is definitely the best Rails ressource on the web. Thank you for your railscasts. I've been watching them for a while and they keep getting better and better.
For those that want to automate the ignores and stuff, I've been happy with the configure_for_svn rake task @ http://snippets.dzone.com/tag/configure_for_svn (just make sure you read all that that task does before using it. I tweak my copy a smidge).
The 'add' task in there is handy too.
Hi Ryan
Markús from Spain, here.
I thing you have forgotten a crucial step in this chapter, it's about setting up svn:executable in the script/ directory and the dispath.* files. This is very important when you are using different machines, Windows workstation for dev and test and Linux server for production. Not everybody uses MacOSX and TextMate (I do, but I have had to work with Windows + RadRails in the past).
Perhaps you might let it to a chapter about deploying rails apps in remote machines, but I miss that in this chapter because it covers all the steps I do when I start a rails app, except that point.
My congratulations for your contribution and your excelent screencasts. You are worthy of generous donations for this.
Thanks.
Hasta luego!
Hi Ryan, these screencasts are great. Thanx a lot for all the effort.
@Todd, yep, exactly. "collection" makes a plural named route (action_tasks_path), "member" makes a singular named route (action_task_path).
Another great screencast. I had one question, though. Is the determination of the plurality of the link generation method (i.e. action_task_path vs action_tasks_path) made by whether you've added it to the collection hash vs. the member hash in the routes.rb file?
@Sintaxi, so right! This is something I often forget.
Something I've noticed with REST is that having a shared find_by_params method saves a bit of repetition. So, you could have:
before_filter :find_task :except => [:index, :new, :create]
def find_task
@task = Task.find(params[:id])
end
Thats great practical information on REST. I think it should be noted that you dont need to create a new model if you want to make those actions RESTful.
If you find yourself creating CRUD like actions to manage your "completed" column. Create only a new (RESTful) controller. This has often worked well for me.
@Manuel, I hear you. I wasn't convinced of REST initially either. I don't think it's possible to convince someone, it's just something you need to try for yourself. Then compare the code before/after - that's what convinced me.
Ironically as it may sound, the biggest benefit of REST is the limitations it brings. It's what keeps your code clean and design normalized.
@Ralph,
Zubin is correct. Also, if you want to learn more, you should buy Peepcode's RESTful tutorial. It's $9, 85 minutes long, and comes with all the source code. It's an excellent resource for REST!
@Ralph, @Merehost:
If you want URLs like "/articles/some-article-title" you can add something like this to the Article model (article.rb):
def to_param
"#{id}-#{name.downcase.gsub(/[^a-z]+/, "-")}"
end
and link to it with article_path(@article)
# do not use @article.id as this will bypass to_params
Thanks for this great screencast! However I'm still not convinced about REST. It's to limiting without bringing too much benefit I think. Maybe in the future...
Ralph:
AFAIK you could implement that as a custom action (find_by_post_title) mapped more or less like that:
map.connect '/articles/:title', :controller => 'articles', :action => 'find_by_post_title'
I'm not sure about the RESTful way, so a big guess would be:
map.resources :articles, collection => {:find_by_post_title => :get}
--
BTW great screencasts ^^
For friendy URLs you can use this plugin http://sargon.interinter.net/acts_as_sluggable/
I've always wondered if I can use custom identifiers for members. For example, I have an articles controller. The show action needs the id of the article, so I have urls like /articles/1. But I want urls like /articles/some-article-title. Is this possible somehow?
I finally understood what was the problem with path not working. I had updated the gems but hadn't updated the version number in environment.rb.
Once I updated it everything worked fine.
Sydney, make sure you call the bundle action while you have your full rails project open in TextMate.
Very cool. But when I try to install from Textmate I get this:
/Applications/TextMate.app/Contents/SharedSupport/Bundles/Rails.tmbundle/Support/lib/rails/text_mate.rb:69:in `method_missing': undefined method `filepath' for TextMate:Module (NoMethodError) from /Applications/TextMate.app/Contents/SharedSupport/Bundles/Rails.tmbundle/Support/lib/rails/rails_path.rb:43:in `initialize' from /Applications/TextMate.app/Contents/SharedSupport/Bundles/Rails.tmbundle/Support/bin/list_plugins.rb:25
Opensource error messages are truly in a world of their own...
That's extremely useful, thanks Geoff!
For those not sure how to install it, add the .rake file to your lib/tasks directory.
Great stuff!
Btw, Errtheblog.com has a helpful rake task to print out all of your named routes, here:
http://require.errtheblog.com/projects/browser/dugg/lib/tasks/err.rake?format=raw
So whenever I need to know what named routes are available for a resource, I just do:
rake routes | grep post
@Gary, what version of Rails are you using? It may require 1.2 but I"m not sure.
For some reason I get a NameError whenever I try to use path but url works great. Is there any reason to believe that path is deprecated or replaced with something else? Or is there something else we need to set somewhere for this to work right?
@Jermaine, yep, I've been using this technique all over the place in previous episodes. Thought it was about time I explained it. :)
absolutely useful tip... even now that I know it, I still can't find the documentation for Time class... so imagine if I didn't know...
Congratulations,
this screencast is fabulous.
Cool!