[ANN] Rails 3.2.3.rc2 has been released!

Rails 3.2.3.rc2 has been released.

IMPORTANT

Rails 3.2.3 introduced a new option that allows you to control the behavior of remote forms when it comes to authenticity_token generation. If you want to fragment cache your forms, authenticity token will also get cached, which isn’t acceptable. However, if you only use such forms with ajax, you can disable token generation, because it will be fetched from meta tag. Starting with 3.2.3, you have an option to stop generating authenticity_token in remote forms (ie. :remote => true is passed as an option), by setting config.action_view.embed_authenticity_token_in_remote_forms = false. Please note that this will break sending those forms with javascript disabled. If you choose to not generate the token in remote forms by default, you can still explicitly pass :authenticity_token => true when generating the form to bypass this setting.

The option defaults to true, which means that existing apps are NOT affected.

This RC includes this authenticity_token change and 2 bug fixes described below. If there are no more release blockers, I will be releasing the final version on March 30th (tomorrow). If you find something please open an issue on github and let me know through email (santiago at wyeworks.com), tweet (spastorino) or cc me on the github issue.

CHANGES since 3.2.3.rc1

Action Mailer

  • No changes

Action Pack

  • Fix #5632, render :inline set the proper rendered format. Santiago Pastorino
  • Fix textarea rendering when using plugins like HAML. Such plugins encode the first newline character in the content. This issue was introduced in https://github.com/rails/rails/pull/5191 James Coleman

Active Model

  • No changes

Active Record

  • No changes

Active Resource

  • No changes

Active Support

  • No changes

Railties

  • No changes

SHA-1

  • SHA-1 (actionmailer-3.2.3.rc2.gem) =
  • SHA-1 (actionpack-3.2.3.rc2.gem) =
  • SHA-1 (activemodel-3.2.3.rc2.gem) =
  • SHA-1 (activerecord-3.2.3.rc2.gem) =
  • SHA-1 (activeresource-3.2.3.rc2.gem) =
  • SHA-1 (activesupport-3.2.3.rc2.gem) =
  • SHA-1 (rails-3.2.3.rc2.gem) =
  • SHA-1 (railties-3.2.3.rc2.gem) =

You can find the list of all changes made between 3.2.3.rc1 and 3.2.3.rc2 here and an exhaustive list of changes between 3.2.2 and 3.2.3.rc2 here.

Thanks to everyone, this is your last chance to hold the release if something goes wrong. So please, give this release a try :).

[ANN] Rails 3.2.3.rc1 has been released!

Rails 3.2.3.rc1 has been released.

IMPORTANT

This release changes the default value of config.active_record.whitelist_attributes to true. This change only affects newly generated applications so it should not cause any backwards compatibility issues for users who are upgrading but it may affect some tutorials and introductory material. For more information see the mass assignment section of the ruby on rails security guide

We’ve also adjusted the dependencies on rack-cache and mail to address the recent security vulnerabilities with those libraries. If you are running a vulnerable version of mail or rack-cache you should update both gems to a safe version. We also fixed a couple of regressions in the render method.

If there are no release blockers, then I will be releasing the final version on March 30th. If you find something please open an issue on github and let me know through email (santiago at wyeworks.com), tweet (spastorino) or cc me on the github issue.

CHANGES since 3.2.2

Action Mailer

  • Upgrade mail version to 2.4.3 ML

Action Pack

  • Do not include the authenticity token in forms where remote: true as ajax forms use the meta-tag value DHH

  • Turn off verbose mode of rack-cache, we still have X-Rack-Cache to check that info. Closes #5245. Santiago Pastorino

  • Fix #5238, rendered_format is not set when template is not rendered. Piotr Sarnacki

  • Upgrade rack-cache to 1.2. José Valim

  • ActionController::SessionManagement is deprecated. Santiago Pastorino

  • Since the router holds references to many parts of the system like engines, controllers and the application itself, inspecting the route set can actually be really slow, therefore we default alias inspect to to_s. José Valim

  • Add a new line after the textarea opening tag. Closes #393 rafaelfranca

  • Always pass a respond block from to responder. We should let the responder to decide what to do with the given overridden response block, and not short circuit it. sikachu

  • Fixes layout rendering regression from 3.2.2. José Valim

Active Model

  • No changes

Active Record

  • Added find_or_create_by_{attribute}! dynamic method. Andrew White

  • Whitelist all attribute assignment by default. Change the default for newly generated applications to whitelist all attribute assignment. Also update the generated model classes so users are reminded of the importance of attr_accessible. NZKoz

  • Update ActiveRecord::AttributeMethods#attribute_present? to return false for empty strings. Jacobkg

  • Fix associations when using per class databases. larskanis

  • Revert setting NOT NULL constraints in add_timestamps fxn

  • Fix mysql to use proper text types. Fixes #3931. kennyj

  • Fix #5069 - Protect foreign key from mass assignment through association builder. byroot

Active Resource

  • No changes

Active Support

  • No changes

Railties

  • No changes

SHA-1

  • SHA-1 (actionmailer-3.2.3.rc1.gem) = 6e945a152d2159918f05dcf4ef72e87d4b75c2bb
  • SHA-1 (actionpack-3.2.3.rc1.gem) = 1c5153c4b4865207193d7e8af9a09b493683bc55
  • SHA-1 (activemodel-3.2.3.rc1.gem) = eae6bb4cc275e167eb28b35cd8b0a46466dd3c88
  • SHA-1 (activerecord-3.2.3.rc1.gem) = 8a2709c7517d9d91911ad3fbfe82af19422b5e24
  • SHA-1 (activeresource-3.2.3.rc1.gem) = 770a7120f8148f6391a717c03f08cdb76dcd64ac
  • SHA-1 (activesupport-3.2.3.rc1.gem) = 1e89864fc28c7b8cca67eb93696f1b2ecf556b81
  • SHA-1 (rails-3.2.3.rc1.gem) = b1dec2b8c59c78111479e3dc36c106e54fe11f1a
  • SHA-1 (railties-3.2.3.rc1.gem) = 9fbbb616cd868d1070bf04adeda50c373550c349

You can find an exhaustive list of changes on github.

Thanks to everyone, this is your last chance to hold the release if something goes wrong. So please, give this release a try :).

Strong parameters: Dealing with mass assignment in the controller instead of the model

We’re exploring a new way to deal with mass-assignment protection in Rails. Or actually, it’s not really a new way, it’s more of an extraction of established practice with some vinegar mixed in for when you forget. This new approach is going to be a part of Rails 4.0 by default, but we’d like your help in testing and forming it well in advance of that release.

Strong parameters

This new approach is an extraction of the slice pattern and we’re calling the plugin for it strong_parameters (already available as a gem as well). The basic idea is to move mass-assignment protection out of the model and into the controller where it belongs.

The whole point of the controller is to control the flow between user and application, including authentication, authorization, and as part of that access control. We should never have put mass-assignment protection into the model, and many people stopped doing so long ago with a move to the slice pattern or a variation there of. It’s time to extract that pattern and bring it to the people.

Example

class PeopleController < ActionController::Base
  # This will raise an ActiveModel::ForbiddenAttributes exception because it's using mass assignment
  # without an explicit permit step.
  def create
    Person.create(params[:person])
  end
  
  # This will pass with flying colors as long as there's a person key in the parameters, otherwise
  # it'll raise a ActionController::MissingParameter exception, which will get caught by 
  # ActionController::Base and turned into that 400 Bad Request reply.
  def update
    redirect_to current_account.people.find(params[:id]).tap do |person|
      person.update_attributes!(person_params)
    end
  end
  
  private
    # Using a private method to encapsulate the permissible parameters is just a good pattern
    # since you'll be able to reuse the same permit list between create and update. Also, you
    # can specialize this method with per-user checking of permissible attributes.
    def person_params
      params.required(:person).permit(:name, :age)
    end
end

We’re still fiddling with the API, but it’s good enough to use now and I’ve replaced our own slice pattern in the new Basecamp with the strong parameters’ approach of permit.

More work to be done

We’re still working on a tidy way to deal with nested parameters, but there’s a design ready for implementation, so it shouldn’t be far off. In addition, Yehuda is going to work on form signing that’ll alleviate the need to manually declare the permitted parameters in the standard HTML form case (you’ll still need to use manually permit parameters for APIs and other clients).

But this is good enough to be useful now. The plugin is currently only fully compatible with rails/3-2-stable rev 275ee0dc7b and forward as well as rails/master rev b49a7ddce1 and forward because of a testing issue with wrapped parameters (if you’re not using wrapped parameters for your json API, you can use the plugin with any version of Rails 3.2).

What is docrails?

Over the years I have seen some confusion about what is exactly docrails and how it relates to the documentation of Ruby on Rails.

This post explains everything you want to know about this aspect of the project.

What is docrails?

docrails is a branch of Ruby on Rails with public write access where anyone can push doc fixes.

If you see a typo, you’d like to correct a factual error, complement some existing documentation, add a useful example… before docrails existed you had to open a pull request (or the equivalent in those days) and follow the ordinary workflow to get it accepted. docrails allows you to clone the repo, edit, and push. Done!

ZOMG, that’s awesome! Tell me more!

Changes to the code base need review before they are pushed. Each individual new feature or bug fix needs the perspective and responsability of core team members to take a decision about it.

Documentation fixes, though, are much more likely to be fine as they are. So, docrails has a public write policy to ease the workflow for contributors.

All commits have to be reviewed anyway, so docrails needs the same effort from Rails committers than going through pull requests, please everyone give big props to Vijay Dev who is nowadays in charge of this time consuming task.

The point of docrails is to provide a way to contribute to the Rails documentation that is fast and easy for contributors.

But wait, I am editing some separate thing?

docrails is a separate branch because it has a different access policy, but you are editing the actual Ruby on Rails documentation.

Every few days, once all new commits are reviewed docrails is merged into master, and master is merged into docrails. Also, very important edits may be cherry-picked into stable branches at the discrection of who merges.

What is allowed in docrails?

You can freely push changes to any RDoc, guides, and READMEs.

No code can be touched at all. That’s a hard rule. No matter how insignificant, not even a one character typo in a string literal.

CHANGELOGs cannot be edited either.

Is docrails a documentation project?

No, Ruby on Rails has no documentation project. Treating documentation as a separate aspect of the project would be similar to treating testing as an external part of the project.

Documentation is an integral part of the development of Ruby on Rails. Contributing a feature or bug fix means contributing its code, test coverage, and documentation.

I am preparing a pull request, should I document later via docrails?

No, docrails is meant only for quick doc fixes.

Pull requests should be complete: code, tests, and docs. If a pull request lacks any of those in general it won’t be accepted as is.

Also, updating docs does not only mean that you edit the RDoc next to the code you are touching. Often the change needs grepping the project tree to find instances of what the pull request is about, to update examples, revise explanations affected by your change, or writing new documentation.

Tidbit: run ack -a to have guides included in the search.

I made a doc fix, when is it going to be online?

Rails releases are a complete set. The documentation itself is part of the release. The fix is going to be online in the stable API or guides websites when the branch that contains the fix gets released.

Edits merged into master are always online in the edge API and edge guides, which are regenerated after every push to master. Thus, edits done via docrails are online in the edge docs website after the next docrails/master cross-merge.

Can I open pull requests for documentation fixes in Ruby on Rails?

Absolutely. Specially if you are unsure about the fix. But if you feel confident just push to docrails.

Please do not open pull requests in docrails.

Note that docrails has no issues tab. The reason is docrails is not a project, as explained above, only a way to bypass pull requests. Documentation issues are Ruby on Rails issues and belong to the Ruby on Rails project just as any other kind of issue.

Does Ruby on Rails has documenters?

No, documentation comes with each push to master. Everyone documents Rails.

The only exception is guide authors. Guide authors take the task to write an entire new guide about a certain topic, and they are allowed to push early drafts to docrails for convenience (only guides in the public index are considered to be published).

That’s for new guides. Once published, guides maintenance happens in master as everything else.

[ANN] Rails 3.2.2 has been released!

Rails 3.2.2 has been released. This release contains various bug fixes and two important security fixes. All users are recommended to upgrade as soon as possible.

CHANGES

For information regarding the possible vulnerabilities, please see the announcements here and here.

Some highlights from this release are:

  • Log files are always flushed

  • Failing tests will exit with nonzero status code

  • Elimination of calls to deprecated methods

  • Query cache instrumentation includes bindings in the payload

  • Hidden checkbox values are not set if the value is nil

  • Various Ruby 2.0 compatibility fixes

For a comprehensive list, see the commits on github.

[ANN] Rails 3.1.4 has been released!

Rails 3.1.4 has been released. This release contains various bug fixes and two important security fixes. All users are recommended to upgrade as soon as possible.

CHANGES

For information regarding the possible vulnerabilities, please see the announcements here and here.

Some highlights from this release are:

  • thrrubyrhino is added to the Gemfile for JRuby users

  • Routing cache improvements

  • Assets group may be skipped with the --skip-sprockets flag

  • Various Ruby 2.0 compatibility fixes

For a comprehensive list, see the commits on github.

[ANN] Rails 3.0.12 has been released!

Rails 3.0.12 has been released. This release contains various bug fixes and two important security fixes. All users are recommended to upgrade as soon as possible.

CHANGES

For information regarding the possible vulnerabilities, please see the announcements here and here.

Some highlights from this release are:

  • require and load will return the value from the superclass

  • ActiveModel confirmation validation fixes

  • Increasing rack dependency

For a comprehensive list, see the commits on github.

Edge Rails: PATCH is the new primary HTTP method for updates

What is PATCH?

The HTTP method PUT means resource creation or replacement at some given URL.

Think files, for example. If you upload a file to S3 at some URL, you want either to create the file at that URL or replace an existing file if there’s one. That is PUT.

Now let’s say a web application has an Invoice model with a paid flag that indicates whether the invoice has been paid. How do you set that flag in a RESTful way? Submitting paid=1 via PUT to /invoices/:id does not conform to HTTP semantics, because such request would not be sending a complete representation of the invoice for replacement.

With the constraints of the methods GET, POST, PUT, DELETE, the traditional answer is to define the paid flag of a given invoice to be a resource by itself. So, you define a route to be able to PUT paid=1 to /invoices/:id/paid. You have to do that because PUT does not allow partial updates to a resource.

Now let’s think about ordinary edit forms in typical Ruby on Rails applications. How many times are we sending a complete representation for replacement? Not always, perhaps we could say that it is even rare in practice that you do so. For example, the conventional created_at and updated_at timestamps normally can’t be set by end-users, though they are often considered to belong to the representation of resources that map to records.

PUT in addition is an idempotent method. You should be able to replay a request as many times as you want and get the same resource, something that sometimes is violated by conventional idioms for creating children resources using nested attributes while updating a parent resource.

There’s nothing theoretical preventing PUT from doing partial updates, but when HTTP was being standarized the replacement semantics were already deployed.

Because of that, the PATCH method was defined in 1995 and standarized later. PATCH is a method that is not safe, nor idempotent, and allows full and partial updates and side-effects on other resources.

In practice, as you see, PATCH suits everyday web programming way better than PUT for updating resources. In Ruby on Rails it corresponds naturally to the way we use update_attributes for updating records.

Thus, PATCH is going to be the primary method for updates in Rails 4.0.

Routing

This is an important change, but we plan to do it in a way that is backwards compatible.

When a resource is declared in config/routes.rb, for example,

resources :users

the action in UsersController to update a user is still update in Rails 4.0.

PUT requests to /users/:id in Rails 4.0 get routed to update as they are today. So, if you have an API that gets real PUT requests it is going to work.

In Rails 4.0, though, the router also routes PATCH requests to /users/:id to the update action.

So, in Rails 4.0 both PUT and PATCH are routed to update.

Forms

Forms of persisted resources:

form_for @user

get “patch” in the hidden field “_method”. The RFC is deliberately vague about the way to represent changes in a PATCH request. Submitting a form is perfectly valid, client and server must simply agree on the accepted ways to update a resource.

Let me emphasize that the “_method” hack is a workaround for the limitations in web browsers. As you probably know Rails routes real HTTP methods. That is, actual PUT, DELETE, and now, PATCH requests are routed to their respective actions.

General availability

PATCH requests are available in all places where the rest of the methods are available today. There is a patch macro for the routes DSL, :via understands the symbol :patch. Tests can issue PATCH requests, request objects respond to patch?, etc. Please see the original commit for details (with an important followup here).

Will my web server understand PATCH?

Yes, it should. I have personally tried Apache, nginx, Phusion Passenger, Unicorn, Thin, and WEBrick. They all understood PATCH requests out of the box.

Also, HTTP clients should be in general able to issue PATCH requests. For example in curl(1) you’d execute:

curl -d'user[name]=wadus' -X PATCH http://localhost:3000/users/1

Credits

We would like to thank David Lee for this contribution and endless patience to keep interested in this even after months of discussion.

Also I would like to highlight the quality of the patch itself. It is excellent: code, tests, all docs revised, comments in code revised. Everything carefully and thoroughly updated. An exemplar patch.

Rails 3.2.0: Faster dev mode & routing, explain queries, tagged logger, store

So we didn’t quite make the December release date as we intended, but hey, why break a good tradition and start hitting release targets now! In any case, your patience has been worldly rewarded young grasshopper: Rails 3.2 is done, baked, tested, and ready to roll!

I’ve been running on 3-2-stable for a few months working on Basecamp Next and it’s been a real treat. The new faster dev mode in particular is a major step up over 3.1.

Do remember that this is the last intended release series that’s going to support Ruby 1.8.7. The master git branch for Rails is now targeting Rails 4.0, which will require Ruby 1.9.3 and above. So now is a great time to start the work on getting your app ready for the current version of Ruby. Let’s not hang around old versions forever and a Sunday like those Python guys :).

There’s a v3.2.0 tag on Github and we of course we still have the 3-2-stable branch as well. You can see all the glorious details of everything that was changed in our CHANGELOG compilation.

For documentation, we have the 3.2 release notes with upgrade instructions, both the API docs and the guides have been generated for 3.2 as well, and there’s a brand new 3.2-compatible version of Agile Web Development with Rails. A smörgåsbord indeed!

Note: If you’re having trouble installing the gems under Ruby 1.8.7, you’ve probably hit a RubyGems bug with YAML that’s been fixed in RubyGems 1.8.15. You can upgrade RubyGems using “gem update —system”.

If you can’t be bothered with the full release notes, here’s a reprint of a few feature highlights from when we did the first release candidate:

Faster dev mode & routing

The most noticeable new feature is that development mode got a ton and a half faster. Inspired by Active Reload, we now only reload classes from files you’ve actually changed. The difference is dramatic on a larger application.

Route recognition also got a bunch faster thanks to the new Journey engine and we made linking much faster as well (especially apparent when you’re having 100+ links on a single page).

Explain queries

We’ve added a quick and easy way to explain quieries generated by ARel. In the console, you can run something like puts Person.active.limit(5).explain and you’ll get the query ARel produces explained (so you can easily see whether its using the right indexes). There’s even a default threshold in development mode where if a query takes more than half a second to run, it’s automatically explained inline — how about that!

Tagged logger

When you’re running a multi-user, multi-account application, it’s a great help to be able to filter the log by who did what. Enter the TaggedLogging wrapper. It works like this:

Logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
Logger.tagged("BCX") { Logger.info "Stuff" } # Logs "[BCX] Stuff"
Logger.tagged("BCX") do
  Logger.tagged("Jason") do
    Logger.info "Stuff" # Logs "\[BCX\] \[Jason\] Stuff"
  end
end

Active Record Store

Key/value stores are great, but it’s not always you want to go the whole honking way just for a little variable-key action. Enter the Active Record Store:

class User < ActiveRecord::Base
  store :settings, accessors: [ :color, :homepage ]
end
 
u = User.new(color: 'black', homepage: '37signals.com')
u.color                          # Accessor stored attribute
u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor