RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

One more thing… I haven't seen a Fileupload plugin which is capable of keeping the temporar file of an upload if the validation fails.

For instance we've the model Medium which has_attachment :file and validates_presence_of :comment. If we left out the comment but specified a :file (let's say a big one... 200MB...) the validation will fail and the data is lost.
It's pretty annoying if you have to upload the file again.

As a workaround you can reflect the validation on client side... but it's not a solution for the problem.

Avatar

Hi,

thanks Koen Van der Auwera.
Another way for solving this is setting PATH as environment variable for Mac OS X 10.5 in /System/Library/LaunchDaemons/org.apache.httpd.plist:

http://gist.github.com/28112

Avatar

Very interesting video, as new to rails and new to javascript in general, I was wondering how to make both work together, but couldn't figure it out because of information overload. This screencasts sums it up pretty well, now all I have to do is learn a bit more javascript and jquery.

Avatar

Fantastic stuff Ryan. If you knew how long I've been trying to understand handling nested models...

Avatar

I created an unobtrusive jQuery screen cast a little while ago inspired by these Railscasts.

http://thenexttrain.co.za/2008/08/screencast-ruby-on-rails-unobtrusive-jquery/

Avatar

Checked my mongrel log and found this: Error reading HTTP body: #<RuntimeError: Socket read returned insufficient data: 10379>

Avatar

I'm using paper clip to upload documents (doc and rtf) it workd fine for a while then it stops suddenly! I can't figure out what's the problem but when I restart my mongrel instance it works fine again... anyone knows anything about it??

Avatar

This broke for me when upgrading to 2.2.2

The content_for capture in application_helper.rb doesn't fail, but it also doesn't insert the stylesheet/javascript into the template.

Any ideas?

Avatar

For some reason when I used Paperclip to resize images for thumbnails it produced files of 0bytes. I had to specify in the model that I wanted jpg files created even if the original was a jpg.

In the following instance the 'small' picture would be fine, but the 'regular' size would be corrupt.

has_attached_file :photo, :styles => { :small => ["100x100#", :jpg], :regular => "300>"}

Avatar

If anyone is having trouble on Windows I've found a solution:
http://ifakedit.com/log/2008/11/21/pretty-rails-logs-in-windows/

It uses MSYS that Git comes with to tail the file. This enables coloring and such.

Avatar

Nice one. I wish this worked with image_submit_tag too.

The name attribute does not not get passed back in the params hash for image_submit_tag

Avatar

Awesome. Thanks so much, Ryan. It seems as though whenever I need to do something which is new for me you have a screencast about it.

Keep up the great work. You rock! :-)

Avatar

DanNewman's method looks better - putting the authorization token in the layout header.

Although I'm wondering if that's a security hole?

Avatar

@Aditya - I had this same exact issue. Here is my solution:

http://pastie.org/320945

(Basically I load the edit form into the page and change _method to 'delete' instead of 'put', and submit :-P)

Ryan - thanks so much! I learned a lot :-)

Avatar

An example of a rake db:migrate:up would be if you are moving from one db to another (ie sqlserver version XYZ.1 to sqlserver version XYZ.2) and have a bunch of imported data (static data) as a migration.

So: rake db:schema:dump on sqlserverXYZ.1, goto sqlserverXYZ.2, do a rake db:schema:load

Then you would rake db:migrate:up VERSION=XXXXXXXXX (your import migrations).

That way - you don't have to worry about sqlserver version dependencies with migrations that may fail due to version incompatablity - but can still use the migration scripts needed to load your static data

Avatar

Thanks Pat, i have almost completed my project into sphinx, and i found sphinx much much easier than ferret. Like it provides default will paginate support and its delta feature is also very very good and useful, Plus provides a lot of default functionalities. Pat i really appreciate and congrates you for developing this wonderful plugin. I also recommend others to use this plugin.

Avatar

Is there a way to make the link_to :delete to be less unobtrusive? I really dont like how it generates a full form in place along with the authenticity_token which means i can't cache anything with that link.

One idea is that we put the authenticity_token in the meta tag/or some other suitable non-cached part of the page with an id and use jquery to scan for delete links and handle the click event on those links to make the correct call to the server along with the authenticity token in place. Anyone already worked on something like that?

Avatar

Fantastic screencast! Helped me refactor some similar stuff I had been doing with Rails and jQuery. For those who'd like to check out another tutorial on this subject, my blog post:

http://polyrails.com/2008/11/11/steps-to-unobtrusive-rails-with-jquery/

Covers AJAX approach leveraging your existing rails templates (eg edit.html.erb) and reporting validation errors w/ jQuery unobtrusive JS.

Avatar

==How to expire paginated pages

So after a lot of research I've figured out how to do this somewhat properly. Short answer is:
def expire_cache(question)
    expire_fragment(%r{public/questions.*})
  end

Here's the explanation:

1. You can't use expire_action, you need to use expire_fragment
2. You need to use a regex

So if you take a look at the source for expire_action and expire_fragment you'll notice that expire_fragment has a "key" passed to it and expire_action does not accept one:

http://api.rubyonrails.org/classes/ActionController/Caching/Fragments.html
http://api.rubyonrails.org/classes/ActionController/Caching/Actions.html

You'll also notice that expire_action is largely just a proxy to expire_fragment if all you're doing is passing it an actual path.

You'll probably want to craft your regex much more elegantly and safely than I have done here, especially if you are caching more than just one thing.

In the end though I see it as an issue with the rails code and expire_action should take the regex as an argument just like expire_fragment does I think.

Avatar

Hey Ryan -

I figured out how to get paginated pages to cache, but I'm having trouble getting them to expire:

def expire_cache(question)
    expire_action "public/questions/"
  end

The index page (page 1) expires properly, but all other pages do not - they cache once and never expire.

I've tried putting * at the end of that path and also including the #{params[:page} at the end of the path (I don't think this should work though since that isn't passed). How can you erase the cache for an entire directory?

Avatar

Franco,
just put jQuery.noConflict() in your application.js, and jQuery will relinquish control of the $ method

Avatar

Great tutorial but not easy to understand. Thanks a lot for our help.

Avatar

any reason a cache sweeper would work in development, but not in production? I'm running passenger and I've tried with both memory store and file store and my sweepers aren't working. They work great in development though.

Avatar

Argh, pastie...

Pull the encryption methods from restful authentication.

    #These are needed to create the salt for user passwords
    def secure_digest(*args)
      Digest::SHA1.hexdigest(args.flatten.join('--'))
    end

    def make_token
      secure_digest(Time.now, (1..10).map{ rand.to_s })
    end
    
    #This is needed to encrypt the user password
    def password_digest(password, salt)
      digest = REST_AUTH_SITE_KEY
      REST_AUTH_DIGEST_STRETCHES.times do
        digest = secure_digest(digest, salt, password, REST_AUTH_SITE_KEY)
      end
      digest
    end

Then populate your user table using these methods:

User.populate 10 do |user|
      user.email = Faker::Internet.email
      user.salt = make_token
      user.crypted_password = password_digest('mypassword',user.salt)
end

Avatar

You can make this work with restful authentication by setting user.salt and user.crypted_password. Pull the encryption methods from restful authentication:

<script src='http://pastie.org/319672.js'></script>

Then populate your user table using these methods:

<script src='http://pastie.org/319680.js'></script>

Avatar

Hi Faisal

Sphinx itself does support this, but it's not yet been implemented in Thinking Sphinx (although I've had someone supply a patch in the last week - I just need to find time to review and possibly merge it).

Avatar

Thanks Pat,Is sphinx providing highlight feature? right now i m using rails helper function for highlight, whether sphinx provide any
functionality like this?.

Avatar

how does this work if my model only has a unique ID column? the "name" is not unique.

Avatar

Hi @all,

do anyone of you know how to include by paperclip generated thumbnails to the to_xml methode?
If I use methods I can specify an array with fields but there I can't say the variation (e.g. small part of photo).

Any ideas?
Thanks for your help,
Steffen

Avatar

I tried for a couple days to make this work with the RESTful authentication. I wanted to add 'roles' to user accounts.

so I have a User class and a Role class. both are HABTM with a proper join table.

I'm not sure exactly what "RESTful authentication" is doing differently, hiding methods or something, but I had to specifically add ":role_ids" in where you specify attr_accessible in the User class.

Analagising this to the example, you'd have to specifically put

attr_accessible :catagory_ids
in the Product class

I'm not sure why this is, but I hope I can save someone some frusteration!

Avatar

Any recommendations against using fleximage? http://github.com/Squeegy/fleximage/wikis

paperclip looks very easy, but so does fleximage. The one thing that really catches my attention about it is the dynamic resizing:
http://github.com/Squeegy/fleximage/wikis/rendering

From what I understand it will render whatever size you want at anytime after the upload, so you don't have to figure out all your sizes in advance and then build your own rake task if you want to make a new size.

Avatar

Those looking for the pagination code, I used this and it seems to work (using restful authentication for the login info):

def index_cache_path
if logged_in? && current_user.has_role?('administrator')
"/admin/questions/#{params[:page]}"
else
"/public/questions/#{params[:page]}"
end
end

Avatar

Solved my issue by installing ImageMagick-6.4.5-8-Q16-windows-dll.exe

Avatar

@Laser Lemon

I am getting the same error on two different machines, a vista and an XP.

I do not have imagemagick installed.

AppData/Local/Temp/stream.2620.0 is not recognized by the 'identify' command.

Avatar

Hey Bryan, as a rails newbi from Germany I love your casts. And with regards to paperclip: my project uses file_column but I would like to switch to paperclip. Do you know how I can make the switch smooth so that I cann still use the so far uploaded Files (path: system/user/picture/<id>/<filename>)? Great if you could help me.
All the best. Im a big fan.
Nick

Avatar

Hi Yves, Laser Demon, all,

I got it working with an intializer: http://gist.github.com/26476 - Passenger + Paperclip that is.

via http://www.fuzzylizard.com/archives/2008/07/05/954/

Avatar

when i use git to install paperclip via "script/plugin install git://github.com/thoughtbot/paperclip.git", i get the following error (after which, if i try to use the paperclip generator, it says it doesn't exist)...

http://pastie.org/318325

If you could give me ANY help i would appreciate it. i can't tell if my git install is screwed up, or if i'm missing something. everyone else seems to have an easy time installing this.

Avatar

@Ryan, correction on my previous comment -- looks like Accept header recognition was re-enabled with this commit:

http://github.com/rails/rails/commit/4ce9931f4f30045b2975328e7d42a02188e35079

Avatar

@Ryan, Great episode! I have always enjoy learning from you. Each episode is like equivalent of a chapter of book, only easier to grasp!

By following your episode, I was able to get my starling and workling working in less than 30 minutes.

@All, Here are just few gotchas based on my experience that I would to share with other people learning.

1. It seems that every time I change the code in the worker, I have to reload the working client; otherwise, change will not take effect.

2. When calling the async_xxx method, its important to spell correctly, otherwise, no warning or error will be given.

Avatar

By the way, can you achieve same technique with jQuery?

http://arturaz.net/blog/?p=545

Avatar

Wasn't there a problem when using Jquery and CSRF protection ?
Do we still need thos kind of hacks : http://errtheblog.com/posts/73-the-jskinny-on-jquery#comment_1154 ?

Great screencast by the way ;)

Avatar

Hi all. Is there some way to keep the prototype working together with jquery?

I would like to migrate to jquery, but I want to do it progressively.

Thanks to the railscast.

Avatar

Ryan, an AJAX validation screencast would be very helpful.

Avatar

What is the benefit of using gems as opposed to plugins?

Avatar

i think jquery is holding totally different ideas from Prototype.
jquery aims to maintain a minimal core for dom & ajax , but prototype is kind of ruby-clone on JS.

Avatar

I just got done with a project where I used jQuery quite extensively. I find it a lot of fun to use, and easier the Prototype because it “is just selector/whistles-and-dongles (effects) framework.” My one big peace of learning from this project was to limit my use of 'id' in my html as much as possible. It is a real nightmare having to name every element you want to use. The selector in jQuery is much more powerful being a superset of CSS3.

My humble suggestion is to initially skip the id for anything that doesn't need it for CSS. If selection is to complex or ambiguous, first try adding a class to an element. Sense classes are reusable, it makes code reuse simple as adding a class to other elements. Your form for example could have been selected simply as $('form') all forms on a page will then submit with Ajax. If this is not appropriate, try $('#some_div form'). Or maybe add an 'ajax' class to the forms that you want to submit asynchronously.

The need to constantly name every element on a page will eventually drive you up the wall.

Avatar

@derek, no merb cast planned (since I want to stay on topic of Rails), but if there's enough interest then maybe.

@Gruszks, I left off validations to keep things simple and because it didn't flow well. I'm also playing around with a few different ways to handle AJAX validations, so maybe it will be a separate screencast.

@Dag, thanks for the tips!

Avatar

"$(document).ready(function() {" can actually be shortened down to "$(function() {" since the default behavior of $() receiving a function is the same as ready on document.

However, I use "jQuery(function($) {", so that it wont be an issue if something overrides the $ variable - it is passed as an argument to the callback here so you wont be accessing the global variable inside the function body. Note that $ is the same as the "jQuery" variable. If you load jQuery last and need $ to be what it was before, you can also call "jQuery.noConflict();" to restore it.

Also worth noting is that semicolons are not often required, but encouraged.