Hacker News new | past | comments | ask | show | jobs | submit login
Ruby on Rails 4.0.0.beta1 released (rubyonrails.org)
302 points by steveklabnik on Feb 26, 2013 | hide | past | favorite | 88 comments



Hello everyone! I am MEGA EXCITED for this release, as it's the first version in which I'm a committer. Wooo! In addition, 954 other intrepid Rubyists in total contributed to this release: http://contributors.rubyonrails.org/edge/contributors

Please note that this is a beta, not an rc, so some things may be a bit wonky. Please file an issue on GitHub and I will do everything I can to help you help us iron out all the kinks.

❤❤❤

(Also, I am on a plane and my battery is almost dead, so I may drop out of this thread soon. Ill read it when I'm home.)


I'm curious to know if these examples of potential SQL injection tested against 3.2.11 have been dealt with in 4.0? Would be great to see these possible problems tidied up.

http://rails-sqli.org/


I am not a member of the security team, but it's my understanding that all security patches were also applied against master where appropriate.

(The security team is a subset of the core team, in accordance with least privilege and all that.)


OK. I've checked against 3.2.12, and at least one isn't fixed, so it might be worth passing the link on to the security team. They'll all be easy fixes, and it'd be great to see them fixed (if not already) in 4.0.

Thanks for contributing Rails 4.0 - I'm excited to try it out, in particular the new caching looks great.


The examples here do not include SQL injection from known CVEs and are not vulnerabilites themselves, only potential misuses of the methods.

What would you like to have changed here? The methods work fine as long as you do not explicitly embed a user-supplied string in a larger SQL fragment.


I don't think all of these examples involve embedding strings. Many people assume that they can use any ActiveRecord method, and as long as they don't embed strings, they'll be safe from sqli. Take this first example:

    Order.calculate(:sum, params[:column]) 
I've just checked in Rails 3.2.12 and this is still possible, haven't checked against Rails 4.0. If I pass in: http://localhost:3000/adverts/1?column=id) FROM users WHERE name = 'Bob' SUM(id;

And do a simple sum in the controller:

    sum = Advert.calculate(:sum, params[:column]) 
    # or 
    sum = Advert.sum(params[:column])
I get:

    SELECT SUM(id) FROM users WHERE name = 'Bob' SUM(id) FROM "adverts" 

Which is not good as it is injecting sql - with judicious use of sql comments etc it could probably be made to execute any sql statement (apparently it does on sqlite with this particular test, but it fails in postgresql which I tested with). Other queries work with psql though [deleted example and reported]. I've reported this with a working example of sqli just in case it is an unreported problem.

Now the intended use of sum, count etc is to deal with symbols chosen by the programmer, but a naive implementation of say an admin form for summing some record attributes might use a param from a form, and pass that in to the sum method for column name, just as they might use params[:id] with find. I think Rails should deal with that.

Also the example given of User.exists? params[:id] is probably commonly used, but vulnerable to manipulation of results at the very least.

I'm not the original author of this page (which is already public and probably has been for some time), and am aware this is not an appropriate place to report bugs, but it would be reassuring if the Rails team looked at this link and fixed anything which is dangerous like the usage above.

IMHO all rails ActiveRecord methods should guard against sqli as much as possible, not just the commonly used ones, and if they don't currently it needs to be fixed.


Ok, this one is a genuine problem in that the method is expected to only deal with column names and is not supposed to accept full SQL, but you made it sound like the page was a list of security issues that Rails should deal with but isn't, which on top of the recent discussions about Rails security sounds a lot like FUD (maybe unintentionally); this is actually a page listing Rails anti-patterns.

If you actually learn Rails and aren't just piecing things together until it works, it isn't a secret that most methods accept raw SQL as the first argument, with optional placeholders for expected values, so if you want escaping you either pass an array ["col1 = ?", params[:val1]] and the values will be quoted or you have to quote explicitly. Methods like .where(), .joins(), .having(), .order() etc. would be crippled if they escaped this first string argument so I am not sure how a "fix" should like here, you have to demarcate somehow which input is trusted and which is untrusted and those methods are 95% of the time used to deal with trusted input.


If you actually learn Rails and aren't just piecing things together until it works

This kind of defensive attitude isn't helpful, I'm quite familiar with Rails since 1.x thanks and want to see it improve, particularly on security issues. I use it every day. I've only quickly looked at this page but as it contains many common antipatterns, and some straight up vulnerabilities, I think it'd be worth fixing everything on it if possible. Having read the above list I'm starting to think I'd be best to convert all params explicitly to the expected type before use, as Rails accepts many varying types for params and this has increased the attack surface. I'm actually pleased there is a spotlight on Rails security right now though as things will improve - much better than no-one but blackhats being interested.

I highlighted two vulns from the list, one in Model.exists? which is expected to take an id param straight from user input, and one in Model.sum,count etc which is more serious but less likely to be encountered as it requires using a column name straight from user input (not advisable). Neither of them take sql as the first argument, one is intended to be an id, and the second a column name. While the above example is a misuse of sum in my opinion, I think Rails should still be a good citizen and deal with it, given the common pattern of Model.query(params[:xxx]) which can be very useful and which many people will pattern their other usage on - any method which takes params directly and not raw sql (i.e. not the ones you list) should I feel be protected against sqli, even or especially if it is not a commonly used one.

Taking security seriously (even if it means inconvenience or working around common user errors) is not FUD, it's a worthwhile process and one which Rails should continue with.


I just think that with your first brief comment you unintentionally scared a lot of people away from Rails, possibly indicating a new release was done but some serious security issues were simply ignored. I had trouble understanding what you meant until you supplied those additional explanations, many thanks for which. I agree the examples you pointed out are problematic, I am just happy we made clear that this is just about 2 or 3 examples from the long list in the link you posted. There is certainly room for improvement in Rails security-wise and I am also happy this is being discussed, as long as the discussion is balanced.


I don't think he scared anyone away from Rails. Rails is not hurting for popularity in any way.


Rather dangerous stuff. I didn't know ActiveRecord would allow to shot yourself in the foot.


Proud to be on the contributor list for this one - any of you considering contributing, it's not hard at all, the team makes it really easy.


I submitted my first contribution, but I never got a response: https://github.com/rails/rails/pull/8903 :(

I suppose it's a lot less of an issue now anyways, but in 3.2, using fetch with memcache with raw objects is super gross since you get totally incompatible responses depending on whether an item existed in cache or not.


Sorry about that. :/

I personally read every single issue, comment, and commit that goes into Rails. But often tickets come up that I don't know anything about, so I don't say anything. This suggestion is one of them; I'm not mega familiar with that part of the codebase.


Any pointers for getting started?


In my opinion the easy way is to look through the github issues and pull requests and understand what's going on. From there, try reading docs and seeing what does / doesn't make sense and editing it. You pretty much always get feedback if you send a decently put together pull request.

Look for places the code might not currently be clear, and try to improve clarity without changing behavior.

Once you've done that kind of thing, sky's the limit as far as I am concerned. I'm working on understanding and improving the parameter parsing behavior at the moment.


Is there any sort of prioritized TODO list, either by difficultly or importance? And that's not so I can knock out some big feature and be the hero, but so I can whittle away at some of the more nagging edge cases and make some random developers day when things just work.


I'd love for you to whittle away at nagging edge cases!

One of the most common places where that's true is in the ActiveRecord issues, which are about half of the open ones: https://github.com/rails/rails/issues?direction=asc&labe...

Even just making a little Rails app or script that re-produces the bug would be helpful. Writing a test case that's failing would be mega helpful. Fixing the bug would be incredibly helpful. :)


The issues page is the best you have for that, sort by popularity or something like that.

That's one of the only things I'm frustrated about - I wish there were a clearer list so that I didn't have to troll for tasks that need doing, or ask a core member on IRC/campfire


Every single issue is something that needs doing. We only keep bugs on the tracker, I'm pretty diligent about shutting them down.


We have a guide here: http://edgeguides.rubyonrails.org/contributing_to_ruby_on_ra...

If there is anything I can do to make this more clear, please let me know. Documentation is something I enjoy.


Definitely check out Rails Dev Box(https://github.com/rails/rails-dev-box) too. It helps to create a virtual environment for testing and running the Rails test suite.

Once you have that installed, you basically don't have to worry about dependencies that you need to bootstrap the Rails test suite.


Upgrade an existing Rails app to 4.0.0.beta1, and fix the issues you come across.


As a rails user, thanks for your contributions! All you guys and gals rock!


I'm not a rubyist but I'm really excited for the russian-doll caching and really hope it catches on in other frameworks. Data dependency tracking makes everything from straight-up caching to real-time updates effortless and I think is one of the few places where an ORM can be really helpful (queue the two hard problems quote about cache-invalidation and naming things). Quora has been doing this since the beginning and I'm surprised it hasn't caught on in other open source (namely python) frameworks to the same degree, hopefully RoR will add some fuel to the fire.


> (queue the two hard problems quote about cache-invalidation and naming things)

I think you meant "cue", otherwise please help a foreigner with this english expression's meaning.. queue onto what?


Yep, you're correct. "Queue" is just the programmer in me typing.


If I remember correctly, Adrian Holovaty said something about exploring pjax solutions for Django when he returned to help manage the project. It would be neat to hear more about his ideas if I missed them posted somewhere...


I am writing an upgrade handbook that covers the important deprecations and new features in detail: http://www.upgradingtorails4.com/


What's the recommended alternative to ActiveRecord Observers? I know they aren't perfect, but I wasn't a fan of cluttering my models with lots of after_commit - is there a better way?


I don't know if it's recommended but for simple cases where I just want to trigger some methods on multiple models I just use a concern: https://gist.github.com/byroot/5036110


They are still maintained, they've just moved to a separate repo/plugin: https://github.com/rails/rails-observers


One option would be to use a service object (e.g. UserCreator) which would encapsulate the action (saving a user) along with the action to be taken (delivering a signup email).

With external observers, it's not always obvious whether they are enabled or not. Service objects make this more explicit and are easier to test as well.


What is the "Rails way" of doing AJAX calls and updating the DOM? I've been embedding Backbone views in the parts of my app that are the most interactive, but I feel like there's gotta be a better way.


It just so happens that one of my major contributions to this release was writing a 'working with JavaScript in Rails' guide: http://edgeguides.rubyonrails.org/working_with_javascript_in...

Others mentioned Turbolinks, but they forgot about remote_form_for and friends.

If you _are_ building a full JavaScript application, Ember.js works really well with Rails + ActiveModel::Serializers. There might be some rough patches until Ember hits 1.0 final, but most of the pieces are in place.


Just want to chime in and say how fantastically ActiveModel::Serializers and the Ember.js REST adapter work together. I built a project with them over the weekend and the experience was overwhelmingly frictionless to a degree I hadn't experienced doing this kind of thing in the past.


Thanks. I've been kinda ignoring AMS in order to get this release out the door, but now that it's out, expect to see much more soon...


Awesome, thanks so much for writing that guide.

JS in Rails had gotten confusing lately, with changes being made over time to supported options and 'golden paths', but insufficient docs on what Rails expected/recommended.

Thanks for working to rectify that!


Any time. Please let me know if any parts of it are confusing; the first example I wrote was pretty bad, and someone chipped in with a way better one. :)


Why is the answer on how to use Javascript to use Coffeescript? Does all RoRists use CS instead of JS, or is it considered best practice?

(I don't use either Ruby, RoR, Coffeescript or Ember.)


In order to use just JavaScript... you just write JavaScript. Nothing special. If you don't want to use it at all, you can also remove the gem from your Gemfile.

> Does all RoRists use CS instead of JS, or is it considered best practice?

It is currently considered best practice to use CS instead of JS, which is why the gem is included in your Gemfile by default. Not every Rails project uses it; Discourse just ported all their stuff to JS, even though they started with CS.


According to recent discussions, turbolinks. It's built into Rails 4 and essentially works by making a call out to the server to fetch raw html and replacing some/all of the DOM with the result.

Personally I just use Backbone and try to structure things in whatever way seems natural. It looks like there's been a lot of work done in integrating Ember.js if you want to look into that.


Turbo links is more suited to traditional web pages.

Backbone for single page mini-apps.


For traditional web pages does it ever make sense to use Backbone/Ember/etc? I've used Backbone on one project and I kind of like the MVC aspect for some things but the thing I'm working on right now is more of a traditional web app. There are some interactive forms where it kind of makes sense to have a model and a view that reacts to changes in the model, but in the end the form is POSTing to a standard rails controller rather than using AJAX calls to update fields when they change. Right now I'm handling that manually since there aren't too many fields but I wonder if using something like Backbone would be a good idea for this use case.


In the recent discussions about Discourse, it was said that on slower connections, it feels way snappier than a server-side solution would be.

Frankly, I'm a server-side guy, so I prefer that kind of development, but there are advantages to SPAs, and like any good engineer, you should use the right tool for the job. Rails is modular enough that you can do whatever you want, Turbolinks is just a gem, so if you don't want to use it, you can just pull it out of the Gemfile.

If be willing to bet that the less dynamic interaction per page, the less an SPA makes sense. ;)

That said, I can also see how something like Ember gives you a nice way to do API-first development, so even if your site is more static, it could make sense.

As always: It Depends. Don't believe anyone who tells you they have a silver bullet.


I agree. I would love to see some article on What TurboLinks actually breaks and How to avoid it. As much as the world love JS and Client Side Rendering. My Experience is that most of these people are either designing it with Chrome in Mind ( And hell yes they are ) or People using other browsers with a single tab at a time. ( Tell me if any single developer test their website in a Multi Tab environment )

Having JS heavy web page will slow down the browsers. That even includes Chrome, you just need a larger number of tabs. On Firefox a few JS heavy site with a slow computer will make your site experience sucks.

Although not a single user would blame the site ( It is always the browsers' fault. ) but to me, most of the time, the less JS the better.

Discourse is pretty fast, but to say 300K zipped JS file is peanuts just doesn't cut it for me ( How about 100K? That is peanuts. ) And again, slow JS execution and loading is something i have zero control of.


> I would love to see some article on What TurboLinks actually breaks and How to avoid it.

The big change is that instead of getting a clean slate every request, you now have one, long-running JavaScript environment. That's where Turbolinks derives its speed from, but it's the biggest change, and this difference in assumption has been where the issues have popped up.

Honestly, I have not followed turbolinks' development very much, so I'd look through the Issues if I were you to get a better idea of what kinds of things have cropped up so far.

> Discourse is pretty fast, but to say 300K zipped JS file is peanuts just doesn't cut it for me

Sure. I think you'd be surprised how quickly you can get up to 300k of assets in a site, though. Plus, you're only fetching it once, it's all cached afterwards. Regardless, as far as I'm concerned, the practice beats the theory. Turbolinks and Ember have both been show to speed up web sites in practice.


I can't comment on Ember or others, but I think Backbone fits into traditional apps just fine. Where I work we're generally a traditional app with many server-rendered pages, but we have a few parts of the site that needed more complex client-side code and we opted to use Backbone for those.

Backbone is a pretty slender library, you can pretty much use it however makes sense to you. You could go really hardcore and do a site that's client-side-everything, or you could do hybrid approach like we did.


Rails 4 uses turbolinks. It is a mechanism that instead of loading a new page loads up the HTML via AJAX and replaces the entire content of the page without reloading all the resources(css, js, etc...)

So instead of having to deal with plenty of small ajax calls you just build an app as it would work in plain HTML and just use turbolinks to leverage AJAX.


Funny that ASP.NET had the same thing, called Smart Navigation, back in 2003.


2003 or 2013, ASP or Rails both are terrible ideas IHMO. At least as a default.

Sure it can be very efficient, but it's a terrible default.

When DHH state: > except, maybe, compatibility issues with some existing JavaScript packages

Some ? Don't you mean most ? Even Twitter Bootstrap will leak memory if used in a turbolink app.

When coffeescript is pushed as default, I'm ok, at worst you don't use it and you have a useless gem. But turbolink is harmful if you don't know what you are doing.


Much further after that, there was a jQuery plugin called taconite that let you do this from arbitrary languages. The idea was that you can handle all of your templating server side and build the template into a simple xml document that had tags corresponding to jquery dom manipulation functions. You return the template with the right mimetype, and the plugin handles translating your xml template into a dom update. This has been handy a few times to keep all of the display logic centralized in a single templating mechanism.


TurboLink does less, so there are less things to screw up.

TurboLink always replace the whole body, not just part of the page. There's no input focus to maintain. Server side render a page the same regardless of whether it's fetched normally or through TurboLink. Links fallback correctly on JS-disabled client.


smart navigation is very different. Besides not being supported across browsers, it was more like automatic anchoring.


Nope, it's not automatic anchoring. It uses JS (iframe AJAX) to retrieve a new page from the server and display it without flicker.


But if two pages have the same resource URLs for their css, js, etc they should be cached by the browser so moving from page to page shouldn't be reloading them.

This does not seem like a super great idea, like merry-christmas mentioned too much like ASP.NET.

I'll do some reading on turbolinks and see if there's something super I'm missing.


I did some speed tests here: https://github.com/steveklabnik/turbolinks_test

Apparently, even though the browser doesn't re-download the assets, it does re-parse and re-execute all of it. Which makes sense. This is where Turbolinks adds the speedup.


does threadsafe and ruby 2.0 mean we can create multiple instances with something like unicorn without forking the entire codebase?


I'm not sure what you mean by 'forking the entire codebase'.

Even if Rails3, though, Rails supported multi-threaded request dispatching IF you had an app server stack that supported it.

In Rails3, you just had to explicitly turn it on with `config.threadsafe!`. Rails4 makes that the default, always on. That's really the only difference. There are at least a few concurrency-related bugs that have been fixed in Rails4 (I'm actually not sure how many), but even Rails3 was officially documented to do multi-threaded concurrent request dispatch just fine. (Actually even Rails 2.2 was!)

Finding a mature, reliable, well-documented app server stack that supports multi-threaded concurrent request dispatch may be harder. I can not say which do and which don't, but there are at least some potential options (including puma, which, if I understand it right, has multi-threaded concurrent request handling as part of it's original core use case).

I AM hoping that Rails4's "multi-threaded request dispatch on by default" situation will make the community pay more attention to this use case, result in more app servers supporting it first-class robustly, and any remaining bugs around concurrency being found and fixed. While Rails3 was documented to support this anyway (since Rails 2.2!), it has been mostly ignored by the community, for some reason.

(Sadly, while Passenger Enterprise 4 will support multi-threaded concurrent request dispatch, the Passenger folks are intentionally reserving this feature for Enterprise, the free one won't)


> Finding a mature, reliable, well-documented app server stack that supports multi-threaded concurrent request dispatch may be harder.

Try Jruby and Puma.


Or JRuby + TorqueBox if you're looking for a stable application server.


You can already run multiple instances of Unicorn. In fact, Unicorn is designed to be a multi-process app server. When running multiple (single-threaded) processes you don't need to be thread-safe. This is the process model that Mongrel and (open source) Phusion Passenger use as well.

But what you probably meant with "multiple instances" is "multiple threads". You can't do multiple threads with Unicorn, it's explicitly designed not to handle multithreading. Instead you should use an app server that's capable of multithreading, e.g. Phusion Passenger Enterprise 4 which is hybrid multi-process/multithreaded.

The Phusion Passenger Enterprise 4 multithreaded stack is already being tested or used in production by multiple organizations. We've been using it in production for months without problems.

Also, multithreading does not require Ruby 2.0. Ruby 1.9 works just fine.


Ruby 2.0 still has the GIL so if you want to run a threaded web server you'll still need to be using rubinius or jruby.


ONLY if it's important to you that one process be able to run multiple threads on multiple CPU cores concurrently.

Even without this, there are MANY use cases where multi-threaded concurrent request dispatch makes a LOT of sense. For instance, the recent controversy about heroku routing, right?

With MRI or another interpreter with the GIL, you'd want to run one app process per CPU core -- but having each of those processes also do multi-threaded request handling can still even out latency (that is, avoid those awful ~95th+ percentile latencies in the heroku routing debacle), and increase overall throughput.

Especially if your app, like most but not all web apps, is more I/O bound than CPU bound (waiting on DB, disk, or external APIs).


Any reason ruby still has the GIL and not moved to a thread implementation?


Matz likes the fact that it Just Works and you can't accidentally have weirdness based on how your code runs. There aren't any plans to remove it at this time.


I can imagine a whole bunch of gems suddenly breaking if this changes...


That's true, but I don't buy that argument: look at how fast everyone has updated their gems to be Ruby 2.0 compatible. The Ruby world likes running on the edge; if MRI forced us to consider thread safety, we'd learn about the issue much quicker as a community. Since we'd be forced to. ;)


Oh I don't doubt that the community would move quite quickly to support it, but it certainly wouldn't be without some bumps along the way!


The GIL makes a lot of things in the Ruby interpreter much easier to implement.


Ruby 2.0 means less memory usage with unicorn since the GC in Ruby 2.0 is copy on write friendly.


Memory savings would be similar to when you used Phusion Passenger or Unicorn in combination with Ruby Enterprise Edition, which also has a copy-on-write friendly GC.


Funny thing about unicorn is, forking is core to its design. It may handle threading now, but when I last looked at its code fork() and traditional IPC via signals were core to its operation. Puma looks like the more thread-oriented choice these days.


Unicorn does not handle threading now. :) It never had, and according to its author never will.

Phusion Passenger Enterprise 4 is also thread-oriented.


Last I looked Puma and jruby were the go-to options for threaded stuff.


Here's an article that shows how to set up both Rails 3.2 and 4.0 with Ruby 2.0. Uses some new features of rvm. "With both versions on your machine, you’ll explore the new features of Rails 4.0 while continuing to develop projects with the most recent stable version."

http://railsapps.github.com/installing-rails.html


Sorry for the naive question... But does this help Heroku's woes?


Nope. The issue at Heroku is before the request has a chance to talk to the rails application. That is why so many people were annoyed that the reporting tool that analyzes speed of the rails application did not report the time lost.


Is the web socket story substantially the same? In other words, Rails just isn't that great a platform for it?

I think Rails is great, but this is one area where it's not a good choice.


The general opinion in the Rails ecosystem seems to be that WebSockets don't solve any real problems and that they are a toy.

The only mentions of WebSockets I've seen from people invested in Rails are mostly made of people actually deriding them and passive-aggressively making fun of people that use them or want to (generally in a bunch with MongoDB, Hadoop, Cassandra or other modern big data tools that don't fall naturally in the Rails ecosystem).

But then again, it's not like they have an infinite amount of time to invest into everything and anything and they worked on SSE for Rails 4 on top of shitloads of additional goodies, patched a lot of security issues so overall I'm pretty happy as an end-user.


We don't do anything specific with WebSockets. ActionController::Live may be able to help you there, in theory, but I'm not incredibly educated on the subject, to be honest.


Is there a Turbolinks equivalent for Django? Or something platform agnostic (I couldn't tell if that was the case with Turbolinks)?


Turbolinks is 100% Coffeescript; you could easily add it to a Django application by copying the assets out of the gem: https://github.com/rails/turbolinks/blob/master/lib/assets/j...


Since Turbolinks is a Ruby gem, it's not exactly platform agnostic :). Hopefully someone else has an answer for Django, but you might take a look at https://github.com/jacobian/django-pjax and http://www.youtube.com/watch?v=3ml88L39cng

Edit: aaand steveklabnik knows more about this than me; listen to him.


How is live streaming implemented?



How well does rails 4 play with mongoid? Any breaking changes I should be aware of?


I'm not sure, because I don't use it, but edge mongoid at least claims to be compatible: https://github.com/mongoid/mongoid/blob/master/mongoid.gemsp...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: