RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

@andy, I can get Ryan's mailit app to worked as detailed -- but, like @Rich -- I'm trying to test the "deliver" method in the controller and get the MemCacheErr. I've gone ahead and added the "Workling::Remote.dispatcher" reference in the config/test.rb as we did in the development.rb but i can't seem to pass go on this one.

My test looks like this http://gist.github.com/12646

I'm getting ready to eject on this one.

Avatar

OK, cancel last statement

followed Ryan's directions precisely this time and now it works - just be sure you ignore the stuff in Workling's README

Avatar

What if my search model uses a HABTM relation.

Where I select multiply options from a checkbox list and want to use them in my search.

Do my model have a string field containing the id's like (11,54,32) or do I create a separate link table?

suppose that my checkbox list is a existing model.

Any ideas?

Avatar

@Wilson - I'm getting the same memcache error

I tried instructions here & from the github plugin site. Neither work. So I'm pulling the plug on this thing, looked nice in the video but my mileage has been zero.

Hope that next weeks idea pans out...

Avatar

I am getting a memcache error.

Workling::WorklingError: MemCache::MemCacheError - No connection to server

Any ideas?

Avatar

is the workling svn the same as the github one?

http://github.com/purzelrakete/workling/tree/master

Avatar

Is there any support for min/max or high/low fields? I have a model that has a price range that is stored as 2 separate fields. I can set pkg.min_price = 1..100 and pkg.max_price = 101..200, but that's not ideal.

Avatar

@Jim in reference to recurring tasks,

I have had great success with this:

http://openwferu.rubyforge.org/rquickstart.html

They renamed it as "Rufus", but it is easier to find up docs for the old name.

Avatar

[@Matt, @Herbalife] It does work with 2.1. There's a route you have to set - see http://gist.github.com/12391

Avatar

Great screencast. I've just begun looking into options for running background jobs (primarily user-triggered - ie. user activation emails, admin alert emails, etc)

Other than the ones mentioned in this thread (Starling, backgroundrb, daemons) I'm also looking at BackgroundJob (BJ) -
http://agilewebdevelopment.com/plugins/bj

Ryan, did you plan on covering this plugin? Anyone have any thoughts or opinions on it?

Thanks.
Jim-

Avatar

Ok after installing the acts_as_list gem I was good to go with porting my app. Now to update my actual rails install I followed this:

http://wiki.rubyonrails.org/rails/pages/HowtoUpgrade

Now when I run rails NewCoolProject I do get the dbconsole etc...

Might help others ;)

Avatar

How does this work if you have a has_one relationship? Say, for example, Project has_one :billing_detail, where BillingDetail belongs_to :project?

I'd like to present the project and it's billing details in one form for new/edit.

Avatar

How would you set up your controller tests? Any chance you could update the mailit code to reflect this? Much appreciated.

Avatar

Also wrt my last comment - I used radio buttons, but mine don't require multiple radios per record, only one because they're selecting one of the records to flag. I got lucky in that what I wanted to do fit the broken situation.

Didn't want anyone to think it was a solution for radio buttons where you need to define a set for each record.

Avatar

I got to try out Michael's multimodel-forms plugin. It works quite well.

I also had to add radio buttons to my stuff and I used Sarah's solution.. I feel this is a much better solution to the problem than using javascript as it is more difficult to validate. Unfortunately right now I've only done this hacked into Michael's plugin and it's not very DRY:

in_attributes.each_with_index do |attributes, j|
# I just added these two lines
attributes["correct_answer"] = attributes.include?("correct_answer_id") ? 1 : 0
attributes.delete("correct_answer_id")

Good stuff guys, it's a big help.

As for validation - any thoughts on server-side validation to make sure there are a certain number of associated (belongs_to) records at all times? So for example you can only make a Book that has at least two Chapters. Or what about something like at least one Chapter has to be flagged (flag column) as "introduction"?

Avatar

More testing (rspec) screencasts please. I get this guilty feeling even mentioning the word.

The community encourages testing, but then just refers me to a peepcode(which are great) or some chapter in a book and carries on.

If testing is so important then why are so few screencasts here on testing? We need someone like yourself to 'glamourize' testing. If every second screencast were about testing I'd feel compelled to think about testing in my everyday coding.

Avatar

@Neil, I believe starling has some persistence built in. If it goes down and there are messages in the queue, it will grab them from the queue log when it starts back up. However, once workling pulls the message from the queue it's up to you to provide the persistence in the Worker class. Usually you can do this by keeping a log of some kind or updating the database during the process. That's rather application specific.

@aleco, the scheduling system I plan to tackle is user driven schedules. For example, the user will be able to choose what time a given mailing goes out. That would be able to handle both user-triggered and scheduled jobs.

Regarding the garbage collection, I'm not certain what the problem is there, but it may be application specific. It sounds like some object never gets freed in the loop.

As for Ruby 1.9 and fibers, I haven't looked in this yet so I can't say much about it. I have a feeling this will get a lot more attention in the coming months as Rails 2.2 goes thread safe.

Avatar

Oh, another question: will ruby 1.9 fibers the new way of spawning background jobs, as they seem to be much nicer to used memory? Ruby libraries such as Neverblock sound interesting, but I'm still somewhat clueless on how to use them (as I'm waiting for a Ruby 1.9 compatible Rails+Mongrel before installing it).

Avatar

Ryan, thanks for the new series on background jobs. As you will start preparing the episode on scheduled jobs in the next few days, may I ask you to also provide a suggestion on how to deal with both scheduled and user triggered jobs, without the need of two background instances (one starling workling, one daemon), aka both scheduled and triggered background jobs within a single background instance?

The reason why I'm asking for this is that memory on the average 256MB VPS host is limited, and still many apps require both scheduled and user triggered jobs. Here's a few examples:

- sending user registration/password emails
- daily calculation of e.g. a kind of "top 10"
- sending daily email newsletter
- background import of data via various APIs

PS: I'm currently using daemons for all this, but my background process keeps growing steadily, which basically forces me to terminate and restart it every few days. I can only assume that GC is optimized for the typical web request, and the infrequent, memory intense methods never really cause a cleanup.

Avatar

Thanks for the great screencast Ryan.

I didn't take a look through the solutions posted from others, but I made some tweaks to allow for multiple announcements and use cookies.

http://pastie.org/277410

Avatar

Another vote here for the Comatose micro-CMS plugin... very easy to integrate with your app and with your existing authentication/authorisation.

http://github.com/darthapo/comatose

Avatar

Ryan, by persistent queue I meant; if something goes wrong and the mailings aren't sent by Starling (maybe someone crashes a truck in to a power station), can we store the jobs in the database so Starling can carry on where it left off?

Avatar

@Jim, you can do that with an endless looping ruby script or rake task which sleeps for two minutes at the end of each iteration. There's no need to use Starling or other background job managers because you don't need to start up jobs arbitrarily. You may want to check out the "daemons" gem for managing this.

On a related note, I do plan to address dynamically scheduled jobs in the next episode.

Avatar

I have jobs that I need to run every 2 mins and some that I need to run every 5 mins. Currently I have just set up various cron jobs to call script/runner and run the jobs. This has the downside of the Rails environment being loaded each time a job is run.

Is there a good way to set up these recurring jobs using Starling?

Avatar

@Tracy, I haven't tried Backgroundrb yet, so I can't really comment on it. From what I've heard many people prefer Starling + Workling due to better memory usage. I also really like Starling's simplicity and how you can interact with it in many different ways. That said, I may do an episode on backgroundrb in the future as it has some additional features.

@Neil, I'm not sure what you mean by persistent queue? This is persistent in the fact that it's always running. It's not starting/stopping a Rails process each time it needs to send a mailing.

Avatar

Cool. Would it take much work in Starling/Workling to turn the Mailings in to a persistent queue?

And let's say you were to run the MailingWorker in both Starling and BackgroundRB; would you expect any performance difference between the two?

Avatar

Hi Ryan,

Thanks you for your screencasts that are so awesome and useful.

Do you know backgroundrb ?
(http://backgroundrb.rubyforge.org/)

I would like to know if you choose starling and workling over backgroundrb. Then, can you give me your reasons ?

I find your solution nice, but i like backgroundrb too. And at that time, i could not see some interesting differences between these two solutions.

Thank you for your light ;-).

Tracy, from Paris :o

Avatar

Hi another great episode!
I was wondering if you plan on doing an episode on google maps in rails? I think a lot of people would like that. Thanks

Avatar

@Tor, I have an episode on caching in Rails 2.1, but it's not specific to MemCache.

http://railscasts.com/episodes/115-caching-in-rails-2-1

Avatar

Great. This sounds like a lightweight easy to use replacement for backgroundrb. Can't wait to try it myself. Thanks :)

Avatar

Thank's
Starling is so easy

do you have MemCache screencast?

Avatar

@Ryan,

You seem to have mispelled 'activerecord_unittest2' in the code that appears at the top of this page (just below 'Resources'), so:

create database activerecord_unittes2;

should actually read:

create database activerecord_unittest2;

Also, I believe you missed the -b flag in:

git checkout named_scope_with_bang

so it should read:

git checkout -b named_scope_with_bang

Avatar

Thanks Walker. I took a slightly modified approach of what you did. I replied in the google group (charlesrc) to your message:

http://groups.google.com/group/rubyonrails-talk/msg/163ada44b0efb1a3

Avatar

I get this error. I'm using rails 2.1

No route matches "/javascripts/dynamics_states.js" with {:method=>:get}

Avatar

@Loïc, good question. I would like to know what people think the best solution for this is too. Ryan answers Mike (comments 2 & 3) by suggesting 'always fetch other models through the associations'. Surely not always?! Is the answer to include the company/domain id in strategic places on the DB? ie Denormalise a bit.

@Ryan. Thanks!

Avatar

Does anyone have a good resource for how to do domain mapping? Basically, the app knows accounts by subdomain, but the web server up the stack does the url rewriting. Haven't found a definitive bullet-proof resource on this.

Thanks,
Bill

Avatar

And of course, as soon as I submit it, I find the github link. :)

Avatar

Here's how I'm trying to populate now... http://pastie.org/276597

I know the last couple of lines won't work, and I know why. I'm just demonstrating how slick it would be if I could. Do you have a github project for the gem, or anything? I'd be happy to help accomplish that if you'd like.

Also, it would be slick if there was something available along the lines of "Populator.bool" that would return an array of true and false, so I don't have to set that up manually in my task.

Thanks a ton for this plugin, it's way slick. Hit me on twitter or GT if there's any way I can contribute. :)

Avatar

Loving the new intro, wonderfully useful tutorial too!

Avatar

Hi Ryan.
I have a problem with this episode.
I downloaded the .tar.gz from the github. Extracted it in my vendor directory.

Now I want to use the new rails to make a new rails project but ofcourse it will still use my old rails version.

Also how did you get that dbconsole script in the existing rails project by just pulling that rails dir into the vendor dir baffles me

Basically there must be some commands I'm missing...

Kind regards and keep up the excellent work!

Avatar

@Cassiano, thanks for pointing out this error! I'll update the code.

Avatar

Hi, and thanks for the great screencast! I am having the following error when I run the rake:

rake aborted!
no such file to load -- spec/rake/spectask

So I read all the comments and tried:
  sudo gem install echoe
and got:
ERROR: Error installing echoe:
echoe requires RubyGems version = 1.2

I am running this on a fresh Rails 2.1 app and have not had any proplems with RubyGems before... Any suggestions?

Avatar

Can we specify a path to a layout? Instead of just the name of layout which is picked from ./views/layouts directory?

I am really interested in some ideas of creating themeing system in Rails. Any good pointers?

Avatar

I used the "generate authenticated user session" and I get the "uninitialized constant SessionsController" error. The suggested route.rb changes don't fix it, as jack says above.

Do I need to back out and redo the generate script? Or are there files I can edit to make session work? Ryan: Why did it work for you and not others? Thanks for any info

Avatar

@Ryan Bates

I think you can use it to limit the number of migrations. So, if you need to change something in an existing migration, just edit it, migrate:down VERSION=xxx, migrate:up VERSION=xxx.

I like this because it keeps me from having a bunch of tiny migrations with column renames.

A little like gist vs pastie.

Avatar

Why can't we just...

class ActiveRecord::Base
  extend ClassMethods
end

to add those module methods as class methods?

Avatar

I just expanded on Ryan's and Jeremy's code... graceful degradation, cookies, and jQuery (jGrowl). See more here:
http://davidwparker.com/2008/09/17/site-wide-announcements-in-rails-using-jquery-jgrowl/

Avatar

@Ryan (re system and background tasks)

You will probably need to end up writing your own background thing, using something like:

Kernel.fork { system()... }

This is more or less what system() does internally. It will more than likely do a few more things (like closing specific file descriptors in the child, and making certain things are correct there.)

Another option is to have a simple shell script (forker.sh?) which you run instead of directly running rake. This shell script could even have commands in it to run "rake ... &" based on input.

Of course, it need not be a shell script, it could be a Ruby script too. All this is more complicated, but in all actuality, I dislike calling programs directly from the Rails framework unless they are intended to display something to the user, or to prod other processes into action.

I have done background tasks before (not in Rails, but in roll-your-own PHP coding) for a large DNS management system. Sometimes actions could take seconds and sometimes hours. We queued up the requests in a database table, and used PostgreSQL's NOTIFY command to tell listeners there was something to do. Doing a periodic (even once a second) SQL query was also added when we had to support MySQL as well. It wasn't a major delay.

Avatar

@Matthew, good point. I'll add that to the code in the notes. As for using Rake, I generally prefer it for two reasons: 1) it's an easy way to load the Rails environment. 2) it is easy to organize and have built in descriptions.

There are definitely times I prefer not using Rake, especially when needing to pass a lot of arguments/options.

@Michael, I originally planned to pass the arguments as separate parameters to system, but then realized this doesn't allow you to end it with "&" or direct the output to something else. Anyone know of a workaround?

Also, good points about security. It's a good idea to be extremely careful whenever passing web parameters to a shell command.