Some Rails "Gotchas" for PHP Devs

Rails is weird, sometimes, for someone used to PHP. Things that have consistently stumped me longer than they deserve to:

"render(:text=>some_obj)" != "exit(var_dump($some_var))"
In PHP, I tend to use the latter as a quick debug step: set $some_var to something that's going wacky, and you'll get a nice display of what it's current contents involve. Originally, I thought render(:text) was going to provide a similar function, but render is not exit — the biggest problem being that Rails will complain if you execute multiple render calls in one controller (and there's always an implicit render!) Rails does have "debug(some_obj)" which is analogous to var_dump, most of the time. For now, I'm using this, plus some time in console, to debug sneaky apps.
Hash.new.is_a? Array == FALSE
In PHP, there's no distinction between Hashes and Arrays. In PHP, [0,1,2,3,4,5] and ['al'=>'bob','carl'=>'dave'] are both true for is_array(). But not in Ruby. This is just a terminology thing; I'm used to (in PHP) seeing an associative list and thinking "that's an array!" I need to get used to seeing these as Hashes now.
Strings and Integers (especially in @params)
I'm totally spoiled by PHP's automagical type-conversion of numerical Strings into Integers. It throws me off balance, in Ruby, to remember that a query string like "?level=3" in Ruby is probably going to come in as an a String and need converting to an Integer. Actually, I like this, overall, because it also forces me to at least think about the possibility of an injection attack.
nil
Yeah, more auto conversion problems. If I had a Canadian 5-cent piece for every time Rails threw me a "You have a nil object where you didn't expect it" error, I could retire for good. Again, the console is your friend, for those times when it's a complete mystery. Also fun: you can't do much with nil, whereas PHP would convert SQL nulls into false/0 as needed, Ruby won't convert nil to 0 for you.
Checkboxes are weird
If you use Rails' built-in check_box helper, it'll generate a hidden "off" field for each check box. Post submit, Rails will munge the fields for you, and you'll get a Hash like this: { "field1"=>"1", "field2"=>"0", "field3"=>"1" } In PHP, I'm used to dealing with checkboxes that aren't always set, giving me something more like: [ 'field1'=>1, 'field3'=>1 ] The net result being: in PHP, I run a lot of "if(isset($response['field1']))"-style checks, in Rails, it's usually safe to assume that something is indeed there, and just check for the state. (I think I will prefer Rails' version eventually, but I'm shaking old habits, at this point.)
Cookies are weird
You can't put a Hash into a Rails-generated cookie. If you send the Hash without any other paramters (eg, "cookies[:some_var] = { 'stuff'=>'doodad', 'food'=>'pickle' }") then the magical Ruby faeries will translate your Hash into parameters, and you'll end up with a blank cookies[:some_var]. On the other hand, if you send in the whole cookie-option package (eg "cookies[:some_var] = { :value => my_hash, :expires => 30.days.from_now }"), you'll get a error message about your Hash not responding to gsub. It turns out, the underlying CGI library that Rails uses for cookies knows to mash Arrays down to Strings, but borks when it gets a Hash. I don't have a good solution to this (yet).
Cookies are especially weird for checkboxes
So, this is why I know that Rails' cookies don't like Hashes: Rails check_box helper makes Hashes. If you try to stick a check_box-generated Hash into a cookie (say, storing user choices for their next visit) it'll bork. Where all this short-circuits, then is the check_box helper expects a "method" that tells it whether or not it should start out checked. "cookies[:this_var]" would be a nice way to handle this, but isn't currently an option.

The Other Thing: Rails & PHP, side-by-side

From reading the mailing list, there's quite a few rails-newbies trying to set this up, but confused on some of the particulars. Usually, it's a developer new to Rails, who doesn't want to lose their existing work while learning the new language. Which is totally a good idea - and accomplishable, within some parameters. Here's my marginally-helpful advice:

  • First, the basics: Rails & PHP involve different interpreters. In almost all cases*, this means you will not be able to call functions in one language from the other. (* Technically, I think you could set up remote services for each, that could then talk to each other, but this is almost always going to be waaay more trouble than it's worth.)
  • On the other hand, you can link back-and-forth between PHP & Rails all day long, and neither will complain. I haven't tried it, but I'm sure you can even get Apache set up in such a way that you can put your PHP files in Rails "/public" directory.
  • For development, it's usually easiest to leave your old work as is - running on whatever server it's currently running on just fine, thank you - and use WEBrick for your new Rails app. In fact, I find WEBrick to be extremely useful for Rails development, I don't think it's worth the effort to set up an Apache/Rails combo on my development machine, but your mileage may vary. This requires no additional set-up: leave your old work as is and start using WEBrick for your new Rails app.

 

Permalink • Posted in: ruby on rails, php, tech stuff, webComments (2)

Comments:

Andy Oct 22, 2006

Hi,

On the Rails & PHP side-by-side question, consider using Lighttpd to run both Rails and PHP (in CGI mode) on the same vhost. It works just fine. Of course, the same limitations apply in terms of sharing data between the two distinct applications, but they always be set up to talk to the same database.

I've found this to be a useful way of replacing a PHP application piece-by-piece with a Rails app without getting bogged down in a complete re-write.

Cheers, Andy

Joshua Oct 29, 2006

Yes, this is true. You can do similar things with LiteSpeed (and Apache, I believe, though I haven't tried it).

At the time I wrote this, I had been seeing a few posts on the Rails mailing list like, "How do I call [PHP Library X] in Rails?" which is a different kind of problem.

Post a comment

  • [required]