Great tip !! Thanks.
However, I think that the sort action
could be made to be more efficient. If I understood right, it generates a separate update for each line, every time the user drags a faq. Better to generate a single update string and execute it after the loop (in the sort action).
@DavidBeckwith: the answers to your questions can be found in the Rack interface specification:
http://rack.rubyforge.org/doc/files/SPEC.html
Note that the body of a Rack app (and middleware are Rack apps) is anything that responds to #each and returns String values. Ryan could have built the body of the response and then prepended it with "..." but, instead, he basically says "the first time #each is called, i'll return my custom string, then i'll just pass the block along to the response's #each".
For more, definitely check out the Rack interface specification or my Rack screencasts @ http://remi.org
I'm new to Rails and trying to write functional tests, a simple test I thought. I have regular users and read-only users, and I wanted to verify that links to add/edit/delete are only displayed for the regular users. Thought I could just do an assert_select to see that an 'a' tag exists with id like 'addLink'. But for some reason the test always fails because it isn't finding the 'a' tag. I cannot find any good references on doing this. Can I just assert_select 'a', 'addLink', or must I somehow traverse through other parts of the view's form? Would appreciate any help, even if it's just pointing me to a location that provides extensive examples of testing controllers and the views they render.
Like other commenters, I ran into an infinite redirect when when using the gem version and a non-valid subdomain on ubuntu and 2.2.2 and script/server.
The fix was simple. Use :subdomain => false on the redirect:
I'm trying to do this same thing except that I want a form that allows a user to create multiple projects and multiple tasks all at once, then save. So I want each project in an array, similar to how each task would be in an array, but I can't seem to separate each project, it just puts all the tasks together. Any thoughts?
I loved this episode, but have a couple issues with engines the way they are in 2.3.
1. I would like to have an easy way to handle the authentication across both apps, not sure if it is possible now.
2. would like to be able to have relationships between the two possibly, say like an item in the store could have posts
3. how do you handle namespaces if they do at all.... say i make an engine and put it on github, but your app uses some of the same names for models as mine did, would be nice if it was namespaced somehow to overcome that.
Thanks Ryan, a very interesting railscast, and the link to rack-contrib helps newbies like me understand what all this rack middleware stuff is good for. :)
I have been trying to get the named scopes to work in my model without any success.
I have model called Contact.
And my named scope is like the follow:-
class Contact < ActiveRecord::Base
named_scope :guardians, {:conditions =>["relationship = ?", 'Guardian']}
And in the IRB:-
>contact = Contact.find(2)
>contact.guardians
gives the following error:
NoMethodError: undefined method `gaudians' for #<Contact:0x636d4e4>
from F:/Projects/WorkshopProjects/testproject/vendor/rails/activerecord/lib/active_record/attribute_method
s.rb:256:in `method_missing'
from (irb):7
I am not sure what is going wrong.
I even tried using lambda as follows, but same thing happens:-
named_scope :test_guardians, lambda { { :conditions => ['relationship = ?', 'Guardian'] } }
FYI for anyone setting up god to monitor workling in a none standard environment. You need to pass the RAILS_ENV which Ryan touched on briefly... However, you need to wrap it with parentheses as so.. RAILS_ENV='staging'... In the Podcast Ryan adds it in as RAILS_ENV=production without parentheses which won't work! PS. I have learned so much from these railscasts it's ridiculous... keep up the great work!
I need to create a payment form which have the "name on card" field and I don't have the field "CVV", can the field "name on card" be sent with the payment and also can the field "CVV" be discarted?
Has anyone solved the collection_select issue. If so I'd love some help. I keep getting the errors described by @joe above.
if I enter a {} for the html options I get a nil object when evaluating nil.attributes=
w/o the {} in my collection_select I get a 500 error... Conflicting types for parameter containers. Expected an instance of Array but found an instance of Hash.
@Amit, good suggestion. That does make things easier to test and elegantly handles the thread-safety issue. One might also consider nesting the body class within the timer. I feel better about keeping them in the same file this way.
http://pastie.org/406597
Ryan,
I've been a big fan for some time now, however one comment:
It seems to me that your essentially using instance variables instead of parameter passing. With the addition to what @Joshua pointed out, this makes this code very hard to test. This example is maybe too simple to illustrate this, but more complex certainly would need some unit tests.
This structure means you would have to either invoke call before invoking each in your tests, or use Object#instance_variable_get, which is ugly at best.
Perhaps a better way might be to create a business object that wrapped response with all the other variables you need:
http://pastie.org/406393
@Dave, I would not use this specific middleware in production because it is not the best way to measure performance. Instead you should use something like NewRelic's RPM. It is also bad to add an HTML comment to the very top of the page before the doctype.
I think Google's response time display is primarily the time the search took to process, I would do that within the Rails app itself and not though middleware.
@Graham, sorry to lose you. This is a fairly advanced topic. Expect some more intermediate content soon.
@Joshua, thanks for pointing this out! I'll update the code so it is thread safe.
@Stephen, right, placing a comment above the doctype is not ideal. This is one reason why I mentioned to not do this in production.
@Shreyans, check out the rack-contrib project linked to in the show notes. That has a lot of production ready middleware examples.
@wlodek, @remi good point! I'll add a note about this.
Awesome thanks for the tutorial and everyone's comments for the help. Just to let everyone else know to get this to work in the edit view I had to do the following additions:
comment #26. Andreas and Björn
and
comment #61. Peer Allan (this code goes in the edit view and for some reason for me I couldn't use a partial for the form...)
Hi Ryan, thanks for this nice episode. One thing I need to request you. It would be too nice of you if you could dedicate one episode on GSA (Google Search Appliance) search. I know many people are using it and it would really help people learn it further if you produce one episode on how to implement GSA search in Rails App.
@Dave Hollingworth: I'm pretty sure Ryan ment that adding a _comment_ before the DTD would not be really useful in production environment. If you want the user to see the response time it might be useful.
@wlodek yep, if you do this for real, you absolutely need to update the Content-Length, and not just for Rack::Lint.
If you add text to the response body without updating the Content-Length, the HTML you see in the browser may be truncated (because the browser is only displaying the *original* number of characters, before you added more text to the response body).
Ofcourse, you can use another middleware to ensure that Content-Length is always set to the length of the response body. Rack comes out of the box with Rack::ContentLength for doing something like this, but I think it only works under certain conditions. It would be easy to write your own middleware to accomplish this, if need be, but it's a good idea for your middleware to always make sure to update the Content-Length, itself.
Middleware seems quite powerfull. I am currently using Sven Fuchs routing-filter plugin so I can support more search friendly urls. I am using it so my cms can respond to resource path's stored in the database (like: host/research/forums). Maybe it could be solved with a middleware instead?
Nice episode. Keep it going.
Ryan, can you give me some more specific areas where it can be used in production environment? I mean more scenarios where it makes sense to use RACK middleware!
The notes say scope.conditions where it should be "scope.scoped conditions". I have just used info in the (excellent) screencast but this time I just checked the notes for reference.
another great screencast as usual - thanks! A quick question - you mention that it wouldn't be a good idea to use your example in a production environment - why not? I'd liker to display the response time on a page (like Google does on a search results page for example), and this looks like a good way to do it. Is there a performance hit by using this perhaps?
@Ryan S : If you want that your rss feed link to "classic" page, You can simply use url_for(:controller => 'articles', :action => 'show', :id => article, :format => nil) instead of the named route.
@Ethan Gunderson : Why did you keep the ":rss" params if you don't use the formatted url...
I found a really cool method for automatically unsharpening generated thumbnails when uploading them through Paperclip. If you've ever been bothered about the fuzziness in your generated thumbnails, you should check this out:
Ryan, thanks for those excellent screencasts, I owe you too much.
I've a problem with my Rails 2.3 installation in development mode:
When I load a page in Safari I've get no response at all, nul, the source code is an empty page, the same for curl but in Firefox it displays allright.
In response to Alex... A good tip, if you have not already thought of this or ruled it out for your specific needs, is to come up with a unique file naming convention to reduce the amount folders needed for categorization. I did some part time work with an image host and they used date-stamping in the file name along with a few other key words to avoid requiring folders. I believe they were hosting around 25k files, so this might still be small scale in comparison if what you may need.
Man, you got a lot of span here, I hope you don't erase this comment together with all those.
I like your approach of using a ':permalink' route for semi-static pages, it's almost a blog but without the publication date or the word "article" prepended in the path.
However, I've been using a different way so far, to make both static and semi-static pages. I might call it "Template Routes", which is nothing less than routes generated from a set of templates in the filesystem. Given this set of templates, a special class converts all files in named_routes, using directories as namespaces to avoid any possible duplicated name. It looks like exactly an old "PHP" or even plain HTML webpage, but it is nothing similar, since I use layouts to change design and common elements without editing all pages one by one.
I've made this for very big static web-sites, when the client needs to put a lot of documentation on a webpage without never or almost never changing it.
Will generate this routes:
## with template about, which renders application too
about
about_harry
about_john
## with template knowledge_base, which renders application too
knowledge_base
...
This names are then easily accessible from any view with the usual *_path helpers, they don't require extra "tunning" in controller, works great with designers and works great with page caching (and don't charge database with data).
Great tip !! Thanks.
However, I think that the sort action
could be made to be more efficient. If I understood right, it generates a separate update for each line, every time the user drags a faq. Better to generate a single update string and execute it after the loop (in the sort action).
Is there a way to insert images into a simple table? I can't get that to work.
@DavidBeckwith: the answers to your questions can be found in the Rack interface specification:
http://rack.rubyforge.org/doc/files/SPEC.html
Note that the body of a Rack app (and middleware are Rack apps) is anything that responds to #each and returns String values. Ryan could have built the body of the response and then prepended it with "..." but, instead, he basically says "the first time #each is called, i'll return my custom string, then i'll just pass the block along to the response's #each".
For more, definitely check out the Rack interface specification or my Rack screencasts @ http://remi.org
Ryan,
I've been watching your railscasts and liked them very much.
In one of them you are watching the contents of development.log on OS X terminal as it changes.
Please let me know the command/tool to watch the runtime changes to the files.
Thanks in advance.
Regards,
Rajan
I'm new to Rails and trying to write functional tests, a simple test I thought. I have regular users and read-only users, and I wanted to verify that links to add/edit/delete are only displayed for the regular users. Thought I could just do an assert_select to see that an 'a' tag exists with id like 'addLink'. But for some reason the test always fails because it isn't finding the 'a' tag. I cannot find any good references on doing this. Can I just assert_select 'a', 'addLink', or must I somehow traverse through other parts of the view's form? Would appreciate any help, even if it's just pointing me to a location that provides extensive examples of testing controllers and the views they render.
Ryan, excellent screencast - thanks!
Like other commenters, I ran into an infinite redirect when when using the gem version and a non-valid subdomain on ubuntu and 2.2.2 and script/server.
The fix was simple. Use :subdomain => false on the redirect:
redirect_to root_url(:subdomain => false)
I'm trying to do this same thing except that I want a form that allows a user to create multiple projects and multiple tasks all at once, then save. So I want each project in an array, similar to how each task would be in an array, but I can't seem to separate each project, it just puts all the tasks together. Any thoughts?
Hello Ryan,
Great screencast as usual. Can you explain a little about
block.call( "... stuff .... ")
@response.each(&block)
How is it that "...stuff..." gets inserted into the response.body by calling the block? And how is that equivalent to "...stuff...." + response.body?
Thank you,
David :)
I loved this episode, but have a couple issues with engines the way they are in 2.3.
1. I would like to have an easy way to handle the authentication across both apps, not sure if it is possible now.
2. would like to be able to have relationships between the two possibly, say like an item in the store could have posts
3. how do you handle namespaces if they do at all.... say i make an engine and put it on github, but your app uses some of the same names for models as mine did, would be nice if it was namespaced somehow to overcome that.
Thanks Ryan, a very interesting railscast, and the link to rack-contrib helps newbies like me understand what all this rack middleware stuff is good for. :)
Hi,
I have been trying to get the named scopes to work in my model without any success.
I have model called Contact.
And my named scope is like the follow:-
class Contact < ActiveRecord::Base
named_scope :guardians, {:conditions =>["relationship = ?", 'Guardian']}
And in the IRB:-
>contact = Contact.find(2)
>contact.guardians
gives the following error:
NoMethodError: undefined method `gaudians' for #<Contact:0x636d4e4>
from F:/Projects/WorkshopProjects/testproject/vendor/rails/activerecord/lib/active_record/attribute_method
s.rb:256:in `method_missing'
from (irb):7
I am not sure what is going wrong.
I even tried using lambda as follows, but same thing happens:-
named_scope :test_guardians, lambda { { :conditions => ['relationship = ?', 'Guardian'] } }
Can you help me out here ?
Thanks in advance.
-Arjun
FYI for anyone setting up god to monitor workling in a none standard environment. You need to pass the RAILS_ENV which Ryan touched on briefly... However, you need to wrap it with parentheses as so.. RAILS_ENV='staging'... In the Podcast Ryan adds it in as RAILS_ENV=production without parentheses which won't work! PS. I have learned so much from these railscasts it's ridiculous... keep up the great work!
Hi,
I have a question about the fields.
I need to create a payment form which have the "name on card" field and I don't have the field "CVV", can the field "name on card" be sent with the payment and also can the field "CVV" be discarted?
Has anyone solved the collection_select issue. If so I'd love some help. I keep getting the errors described by @joe above.
if I enter a {} for the html options I get a nil object when evaluating nil.attributes=
w/o the {} in my collection_select I get a 500 error... Conflicting types for parameter containers. Expected an instance of Array but found an instance of Hash.
@Amit, good suggestion. That does make things easier to test and elegantly handles the thread-safety issue. One might also consider nesting the body class within the timer. I feel better about keeping them in the same file this way.
http://pastie.org/406597
Ryan,
I've been a big fan for some time now, however one comment:
It seems to me that your essentially using instance variables instead of parameter passing. With the addition to what @Joshua pointed out, this makes this code very hard to test. This example is maybe too simple to illustrate this, but more complex certainly would need some unit tests.
This structure means you would have to either invoke call before invoking each in your tests, or use Object#instance_variable_get, which is ugly at best.
Perhaps a better way might be to create a business object that wrapped response with all the other variables you need:
http://pastie.org/406393
This is both thread safe *and* testable
Excellent!
+1 recurring billing!
@Dave, I would not use this specific middleware in production because it is not the best way to measure performance. Instead you should use something like NewRelic's RPM. It is also bad to add an HTML comment to the very top of the page before the doctype.
I think Google's response time display is primarily the time the search took to process, I would do that within the Rails app itself and not though middleware.
@Graham, sorry to lose you. This is a fairly advanced topic. Expect some more intermediate content soon.
@Joshua, thanks for pointing this out! I'll update the code so it is thread safe.
@Stephen, right, placing a comment above the doctype is not ideal. This is one reason why I mentioned to not do this in production.
@Shreyans, check out the rack-contrib project linked to in the show notes. That has a lot of production ready middleware examples.
@wlodek, @remi good point! I'll add a note about this.
@Martin.
I got round this problem with the respond_to block.
I added it at the end and specified that the .js format would have no layout :layout => false
@Shreyans:
I blogged a little while back about how I used middleware to help with a flash file uploader:
http://tinyurl.com/desshu
While the middleware doesn't look like it does much, it replaces a much more hacky and lengthy solution that had to be used in the 'olden days' :D
Awesome thanks for the tutorial and everyone's comments for the help. Just to let everyone else know to get this to work in the edit view I had to do the following additions:
comment #26. Andreas and Björn
and
comment #61. Peer Allan (this code goes in the edit view and for some reason for me I couldn't use a partial for the form...)
Hope this helps anyone. thanks again Ryan!!
Why the locale files are not included within rails ? It's would be easier to update. And every rails version will have the same locales files.
Hi Ryan, thanks for this nice episode. One thing I need to request you. It would be too nice of you if you could dedicate one episode on GSA (Google Search Appliance) search. I know many people are using it and it would really help people learn it further if you produce one episode on how to implement GSA search in Rails App.
@Ryan: Nice screencast, as usual.
@Joshua Peek: +1, except I would rename '_call' to the more conventional 'call!'.
@Dave Hollingworth: I'm pretty sure Ryan ment that adding a _comment_ before the DTD would not be really useful in production environment. If you want the user to see the response time it might be useful.
Cheers,
David Knorr.
@wlodek yep, if you do this for real, you absolutely need to update the Content-Length, and not just for Rack::Lint.
If you add text to the response body without updating the Content-Length, the HTML you see in the browser may be truncated (because the browser is only displaying the *original* number of characters, before you added more text to the response body).
Ofcourse, you can use another middleware to ensure that Content-Length is always set to the length of the response body. Rack comes out of the box with Rack::ContentLength for doing something like this, but I think it only works under certain conditions. It would be easy to write your own middleware to accomplish this, if need be, but it's a good idea for your middleware to always make sure to update the Content-Length, itself.
Middleware seems quite powerfull. I am currently using Sven Fuchs routing-filter plugin so I can support more search friendly urls. I am using it so my cms can respond to resource path's stored in the database (like: host/research/forums). Maybe it could be solved with a middleware instead?
I think, that @headers['Content-Length'] should by updated to reflect the change in the response length. Otherwise Rack::Lint will complain.
Nice episode. Keep it going.
Ryan, can you give me some more specific areas where it can be used in production environment? I mean more scenarios where it makes sense to use RACK middleware!
A really nice overview, but with a potential gotcha for those that that use the example in a real app:
Nothing should ever appear before the DOCTYPE.
You'll start seeing some definite quirks in different browsers if anything not-DOCTYPE comes first, including comments.
If anyone wants a more in-depth look at how to write Rack Middleware (and Rack apps), you might like my Rack Middleware screencast:
http://remi.org/2009/02/28/rack-part-3-middleware.html
Thanks for showing off all of the sweet things that we get with Rails 2.3, now that Rails has such awesome Rack support :)
Awesome!
Maybe not a huge concern for your example, but it is not threadsafe. You should never modify instance variables in the call method.
However, there is a quick trick to get around this: http://pastie.org/404695
Never mind, my memory is dodgy. The syntax in the notes is the refined version. Sorry :-)
Just a small typo:
The notes say scope.conditions where it should be "scope.scoped conditions". I have just used info in the (excellent) screencast but this time I just checked the notes for reference.
Sounds useful, but I have to admit you lost me on this one Ryan. Lots of unfamiliar territory.
@Steve
Cool, that does it!
Thanks
Ah, the #151 is here ! Very good Ryan, as always ! ;-) I hope a #1000 and even a #2000. ^^
Interesting screencast as usual, thank you!
Hi Ryan,
another great screencast as usual - thanks! A quick question - you mention that it wouldn't be a good idea to use your example in a production environment - why not? I'd liker to display the response time on a page (like Google does on a search results page for example), and this looks like a good way to do it. Is there a performance hit by using this perhaps?
I'm really enjoying your Rails 2.3 screencasts.
Thanks again.
@Ryan S : If you want that your rss feed link to "classic" page, You can simply use url_for(:controller => 'articles', :action => 'show', :id => article, :format => nil) instead of the named route.
@Ethan Gunderson : Why did you keep the ":rss" params if you don't use the formatted url...
Hey Ryan,
Awesome! Just one question. How come you put the javascript that handles the form submit in application.js and not directly in the view?
I found a really cool method for automatically unsharpening generated thumbnails when uploading them through Paperclip. If you've ever been bothered about the fuzziness in your generated thumbnails, you should check this out:
http://natemiller.org/2009/2/28/automatically-unsharpening-thumbnails-with-rails-and-paperclip
I create a better version of the patch, and extracted into a plugin.
LH ticket: http://tinyurl.com/b2acxp
Plugin: http://github.com/jodosha/plugin_migrations/tree/master
Enjoy!
Ryan, thanks for those excellent screencasts, I owe you too much.
I've a problem with my Rails 2.3 installation in development mode:
When I load a page in Safari I've get no response at all, nul, the source code is an empty page, the same for curl but in Firefox it displays allright.
Any sugestions?
In response to Alex... A good tip, if you have not already thought of this or ruled it out for your specific needs, is to come up with a unique file naming convention to reduce the amount folders needed for categorization. I did some part time work with an image host and they used date-stamping in the file name along with a few other key words to avoid requiring folders. I believe they were hosting around 25k files, so this might still be small scale in comparison if what you may need.
Ryan, I just want to say thank you for all your great work. Each week a great highlight. Please continue !!!
Thanks !!!
I can't seem to get rails to use the template from github.
It just sits at "applying template: http://github..."
and eventually times out. Can anyone help?
Thanks for another great screencast Ryan.
I am getting some errors like this--"Security header is not valid."
Hi Ryan.
Man, you got a lot of span here, I hope you don't erase this comment together with all those.
I like your approach of using a ':permalink' route for semi-static pages, it's almost a blog but without the publication date or the word "article" prepended in the path.
However, I've been using a different way so far, to make both static and semi-static pages. I might call it "Template Routes", which is nothing less than routes generated from a set of templates in the filesystem. Given this set of templates, a special class converts all files in named_routes, using directories as namespaces to avoid any possible duplicated name. It looks like exactly an old "PHP" or even plain HTML webpage, but it is nothing similar, since I use layouts to change design and common elements without editing all pages one by one.
I've made this for very big static web-sites, when the client needs to put a lot of documentation on a webpage without never or almost never changing it.
For example, a directory tree like this:
views/
templates/
about/
harry.html.erb
john.html.erb
about.html.erb
knowledge_base.html.erb
...
layouts/
application.html.erb
about.html.erb
knowledge_base.html.erb
Will generate this routes:
## with template about, which renders application too
about
about_harry
about_john
## with template knowledge_base, which renders application too
knowledge_base
...
This names are then easily accessible from any view with the usual *_path helpers, they don't require extra "tunning" in controller, works great with designers and works great with page caching (and don't charge database with data).