What's New in Edge Rails

Posted by Nathaniel Bibler October 12, 2009 @ 09:40 PM

So, Edge Rails is still chugging right along. There are new and interesting fixes, changes, and refactors going on all of the time. So, lets take a look at just a few that've gone in since the last post (it's been a while, I know, I'm sorry!).

ActionView and Helpers

XSS escaping is now enabled by default. This means that if you want to explicitly output HTML to your views, you'll probably have to mark it as html_safe! before sending it through.

<%= 'my <a href="http://www.rubyonrails.org">safe</a> string'.html_safe! %>

Many of the built-in helpers have been updated for this change and if you see an issues with the Rails helpers being incorrectly sanitized, you should create a new ticket.

distance_of_time_in_words has gained 'over', 'about', and 'almost' keywords, thanks to Jay Pignata and John Trupiano. This provides you with an improved level of granularity when approximating the amount time passed. So, instead of just "2 years ago", it can now also report "almost 2 years ago," "about 2 years ago," and "over 2 years ago," depending on the proximity to being exactly 2 years old.

assert_equal "almost 2 years",  distance_of_time_in_words(from, to + 2.years - 3.months + 1.day)
assert_equal "about 2 years",   distance_of_time_in_words(from, to + 2.years + 3.months - 1.day)
assert_equal "over 2 years",    distance_of_time_in_words(from, to + 2.years + 3.months + 1.day)
assert_equal "over 2 years",    distance_of_time_in_words(from, to + 2.years + 9.months - 1.day)
assert_equal "almost 3 years",  distance_of_time_in_words(from, to + 2.years + 9.months + 1.day)

The HTML form helper, fields_for - generally used for nesting additional model forms - now allows for explicit collections to be used, thanks to Andrew France. So, instead of just including all of your blog.posts, you should have it only display your published blog.posts, for example. Or:

<% form_for @person, :url => { :action => "update" } do |person_form| %>
  ...
  <% person_form.fields_for :projects, @active_projects do |project_fields| %>
    Name: <%= project_fields.text_field :name %>
  <% end %>
<% end %>

API Change for content_tag_for: The third argument - being the optional CSS prefix - will now also affect the generated CSS class. This prefix will now be appended to the generated element's CLASS attribute.

<%= content_tag_for(:li, @post, :published) %>
# => <li id="published_post_123" class="published_post">...</li>

ActiveResource and ActiveRecord

Taryn East has added update_attribute(s) methods to ActiveResource. These methods act very similarly to the ActiveRecord methods we already know and love.

Building or creating an object through a has_one association that contains conditionals will now automatically append those conditions to the newly created object, thanks to Luciano Panaro.

class Blog
  has_author :commit_author, :class_name => 'Author', :conditions => {:name => "Luciano Panaro"}
end

@blog.build_commit_author
# => #<Author name: "Luciano Panaro" ... >

Pratik Naik added a new option to ActiveRecord's accepts_nested_attributes_for to :limit the number of records that are allowed to be processed. Also, while we're covering accepts_nested_attributes_for, José Valim as renamed the _delete option to _destroy to better follow what is actually occurring. A deprecation warning has been added to _delete, for the time being.

Jacob Burkhart updated the new autosave option in Rails 2.3 to allow for an :autosave => false, which will disallow saving of associated objects, even when they are new_record?s.

Some Internals

Previously, CDATA elements could be ignored when converting from XML to a Hash, so now, thanks to John Pignata, Hash#from_xml will now properly parse and include CDATA elements values.

Josh Peek has relocated global exception handling into ActionDispatch::Rescue. So, this is now being handled at the Rack middleware level.

And finally, Yehuda Katz and Carl Lerche began work on a Rails::Application object to better encapsulate some of the application start up and configuration details. Also, a good bit of initialization has now gone on to move into this new object.

Remember, if you prefer to have a shorter audio summary of some of this content and more, you should check out the Ruby5 podcast over at Envy Labs; it's released every Tuesday and Friday with the latest news in the Ruby and Rails community.

Photo: Clock Tower by Brian Taylor

Posted in Edge | 17 comments

Comments

  1. Sleepless on 13 Oct 03:18:

    Cool updates. When’s the approximate release date for RoR 3?

  2. mrkris on 13 Oct 03:58:

    Not sure I like having to call html_safe! I don’t need my hand held, I’m an adult and can make my own decisions, after all, this is Rails, not PHP + safe_mode

  3. Jude on 13 Oct 04:01:

    Nice information, when can we expect the release

  4. Tomash on 13 Oct 06:28:

    As for html_safe!, I actually preferred xss_terminate and white_list_model approach, i.e. stripping all the nasty stuff before it’s saved into database and leave the views intact.

  5. Brian Rose on 13 Oct 06:40:

    I believe you can also use the raw helper:

    <%= raw unsafe_string %>

    It simply calls html_safe! on the string, but is a lot clearer.

  6. Jan on 13 Oct 08:32:

    That html_safe! thing is going to break a ton of old code. I do hope there is an option to switch it off or I don’t see myself upgrading all earlier code. (Looking at the code it seems relatively easy to monkey patch it into something without side effects, but I’d rather not)

  7. iGEL on 13 Oct 14:47:

    I believe, the html_safe!-thing is a good decision. Sure, it’s gonna break some things, but you can’t forget to escape something anymore.

  8. Bob on 13 Oct 15:35:

    So everywhere I’ve properly used <%= h @customer.name %> is now going to show “Crate & Barrel”. Or am I missing something? Is it smart enough to know that something passed through h() doesn’t need to be escaped a second time?

    And since all the standard helpers had to be modified for this, I assume our helpers will also have to be similarly modified?

    If so, it’s a seriously stupid change. Welcome to PHP.

  9. John on 13 Oct 19:56:

    Another -1 for the XSS escaping change. At the very least we need a config option that will allow it to work the old way.

  10. Bruno on 13 Oct 20:51:

    I think that the on-by-default XSS escaping is a good thing.

    @mrkris: Rails escaping is not comparable to PHP + safe_mode. It’s more like the django approach.

    @Bob: strings passed through h() are marked as html_safe, so they won’t be escaped a second time. It’s also the case for Rails helpers like link_to.

  11. Michael Economy on 14 Oct 06:32:

    Can we get a better write up for how this html_safe stuff its actually going to work?

    I’m definetly in favor of having an option to disable it. If i wanted to protect myself from coding I’d write Java. The prospect of refactoring over a hundread thousand lines of .erb files isn’t particularly attractive either.

  12. Kevin on 14 Oct 13:37:

    I agree with moving to XSS escaping by default, but it is essential that we have a smooth upgrade path that doesn’t break legacy code.

    +1 for adding a config option to disable it until developers are ready to switch.

  13. Jones Lee on 14 Oct 13:38:

    I myself prefer to have XSS escaping enabled by default. The time it takes to refactor your code is cheaper than the cost of XSS security exploits. I think this makes Rails unique and better than other frameworks because a framework should enforce a convention for everyone or else it’s not much different from ZendFramework, which is a bundle of libraries.

  14. Yuval on 14 Oct 16:21:

    I would also like to see a clearer write up of the new html_safe code. As it stands, its unclear how it relates to the existing sanitize and h methods. If you want to whitelist html in a string, do you need to call sanitize and html_safe?

  15. Farid on 16 Oct 14:04:

    Thank u for this post. and gratulations for the new lineup! greez from germany

  16. Geoff on 18 Oct 22:52:

    It seems odd to me that ‘distance_of_time_in_words’ is part of core. It seems like it should really get moved out into a plugin…

    Thanks for the update!

  17. Zack on 29 Oct 14:01: