Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker

Monthly Archives: May 2007

Rails Filter Parameter Logging

Alex Chaffee
Wednesday, May 30, 2007

Q: How do you keep passwords from appearing in plain text in your Rails log file?

A: Filter Parameter Logging

filter_parameter_logging
=> Does nothing, just slows the logging process down

filter_parameter_logging :password
=> replaces the value to all keys matching /password/i with "[FILTERED]"

filter_parameter_logging :foo, "bar"
=> replaces the value to all keys matching /foo|bar/i with "[FILTERED]"

filter_parameter_logging { |k,v| v.reverse! if k =~ /secret/i }
=> reverses the value to all keys matching /secret/i

filter_parameter_logging(:foo, "bar") { |k,v| v.reverse! if k =~ /secret/i }
=> reverses the value to all keys matching /secret/i, and
   replaces the value to all keys matching /foo|bar/i with "[FILTERED]"

(Note that :password matches password_confirm too.)

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Joe Moore

Standup 05/24/2007

Joe Moore
Friday, May 25, 2007

Interesting Things

  • We’re looking for the best search plugins for Trac. Suggestions?
  • Rails: We often find ourselves adding and return in our Controllers to avoid the dreaded DoubleRenderError. It turns out that you can use unless performed? instead:
<code>
def double_rendering_action
  render :template => "wrangler/monkey" if wrangle_monkey?
  render :template => "wrangler/sleep" unless performed?
end
</code>
  • Textmate Footnotes Plugin in Ruby on Rails will give you hyperlinked error messages that will open TextMate the the appropriate line of code.
  • We’ve released our distributed page caching solution on the Pivotal RubyForge project!
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

REST: Theory to practice

Pivotal Labs
Thursday, May 24, 2007

REST. What is it, and how can it be used to design better web applications?

A presentation at RailsConf did me a great service by first pointing out all the things REST is not. It isn’t CRUD. It isn’t pretty URLs. It is neither a protocol nor an architecture, but it can play a role in your implementation of all of the above. REST itself though, is less concrete than all of that. It is a theoretical framework, a way of thinking about designing distributed software systems. For me, the first step in absorbing its principles is to forget about the database and focus on the fundamentals. This article will start there, then drill down to show how these ideas can help organize the development of your Rails applications.

Noon: Rest From Work (After Millet) by Van Gogh

(Noon: Rest From Work (After Millet) by Vincent Van Gogh)

REST encourages a focus on resources. A resource is anything that can be named, and your system can have as many resources and corresponding names as you want. Conversely, there is a limited set of operations defined on those resources. Unlike objects in object-oriented programming languages, which support very diverse, rich interfaces, resources in a RESTful system are relatively uniform. So how can a sophisticated API be developed if REST requires a fixed and limited number of operations that resources can support? The answer: add more resources!

Lets play with an example. Say I’m writing a web application that has a collection of shapes that can be moved to new locations. In an object oriented program, I might have a move method defined on each shape, but in this RESTful API, I have assigned consistent semantics to a limited set of operations supported by the HTTP protocol. I can show GET, create POST, update PUT, and destroy DELETE my resources. Nowhere in the HTTP specification is the a MOVESHAPE method defined. A naiive approach to remedying this limitation is to shoehorn this operation into the protocol by abusing URLs.

http://againstgrain.com/shapes/move/1

I call this abuse because URL stands for uniform resource locator, and it’s very hard to see this imperative-style command encoding as much of a resource. This is an API decision that fights the nature of the protocol it uses. How can the API go with the flow?

There are many potential solutions. Let me outline two, the first very simple, the second more sophisticated.

The first solution is to recognize that a move operation is just a change to the location of an object. If we expose this location as a resource and allow it to be updated, we’ll implement movement in a natural way without contorting URLs to name things that aren’t actually resources:

So we combine one of the four standard operations:
Update, represented by an HTTP PUT

With a resource:
http://withgrain.com/shapes/1/location

Updating the location of the shape will naturally equate to moving it.

But what if we want the movement to be relative to the objects current position, so that the client can say that they want a shape to move 5 pixels up and 10 pixels to the right without needing to know the objects current position or do any computation? To solve that problem, we apply a technique I learned doing computational semantics: reification.

Reification means that we give solid form or objecthood to something formerly fleeting or ephemeral. Anything can be reified. The fact that I am named Nathan Sobo can be thought of as my NathanSoboness, which is an (albeit abstract) conceptual object. Here we’ll apply the technique in a more conservative fashion, and say that shapes are associated with a history of movements. This movement history is a collection, which is itself a resource.

http://withgrain.com/shapes/1/relative_movements

Now say we want to move the shape. We combine the above resource locator with one of our standard operations, create, implemented as an HTTP POST. By posting a new movement to a shapes history, we cause the shape to move.

Now we’re working with HTTP rather than around it.

So how does this transfer to the design of Rails applications? Embracing resource oriented application development means you’ll be writing more controllers with fewer, more consistent methods. Lets work through a potential implementation of the shape API in Rails. It will all start in the routes file, with map.resources…

Lets say we want to expose both the relative and absolute means of moving a shape. First we’ll start with a shapes resource.

map.resources :shapes

This represents the collection of all shapes in our system. It assumes the existince of a corresponding ShapesController and will set up a series of routes and url-generating methods to help reference the actions therein. Note the controller and its standard complement of methods below.

class ShapesController < ActionController::Base
  def index
  end

  def show
  end

  def create
  end

  def edit
  end

  def update
  end

  def destroy
  end
end

But with map.resources, the actions on the controller do not play a critical role in the url. They merely name the operations to which a given pairing of HTTP request method and URL will map. GETting /shapes will execute index. POSTing to /shapes will execute create. GETting /shapes/:id will execute show. PUTting to /shapes/:id will execute update, and DELETEing /shapes/:id will execute destroy. So even though there are 5 actions, there are really only two url patterns, one referencing the resource that is the collection of all shapes, and another referencing resources that are members of that collection. We can reference these URLs with automatically defined methods:

shapes_url ---> /shapes
shape_url(@square) or shape_url(@square.id) ---> /shapes/1

By pairing these with the correct HTTP method, we can access every operation we need.

Now lets add relative movement:

map.resources :shapes do |shape|
  shape.resources :relative_movements, :name_prefix => 'shape_'
end

class RelativeMovementController < ActionController::Base
  ...
end

This again assumes the existence of a RelativeMovementController with all of the standard methods defined on it. Except the resources supported by this controller are nested within shape resources, so the URL patterns look like this:

/shapes/1/relative_movements
/shapes/1/relative_movements/4

Because of the :name_prefix supplied (which will no longer be needed at some release of Rails in the future), we can refer to these URLs with helper methods that look like this:

shape_relative_movements_url(@triangle) ---> /shapes/1/relative_movements
shape_relative_movement_url(@triangle, 4) ---> /shapes/1/relative_movements/4

All of the same rules about HTTP method choice allow access to the RelativeMovementController‘s actions.

Now a cool twist: Singleton resources. Lets add the nested position resource to shapes.

map.resources :shapes do |shape|
  shape.resources :relative_movements, :name_prefix => 'shape_'
  shape.resource :position, :name_prefix => 'shape_'
end

And a corresponding controller, this time with a different complement of methods:

class PositionController < ActionController::Base
  def show
  end

  def edit
  end

  def update
  end
end

Because position is a singleton resource nested inside of shape, this controller is designed to deal with a single resource rather than a collection of them, so there is no need for an index action. The HTTP verb / URL combination mappings are also different. So PUTting to /shapes/1/position will invoke the update action.

None of these changes are Earth-shattering, but the simple act of focusing on resources is a force that will organize your application. Rather than growing a hodgepodge of actions on ever fattening controllers, you’ll instead create a greater number of controllers that are more circumscribed in their responsibilities.

What does this say about your model? Not much. I used to think that it was important to have a controller for every model object, and I no longer do. Controllers are responsible for supporting the exposure of resources to a remote API. This collection of resources is, in a sense, your remote client’s model. Whether your resources map precisely onto your underlying data model is your business. For example, you might expose resources that have no direct correspondence in the model layer. Or you might have model objects that you don’t choose to expose as resources.

But regardless, REST finally provides an organizing principle for the controller layer. Even if you don’t plan on exposing a RESTful API as a service, thinking in terms of resources will help you build more consistent applications and help you make fewer decisions.

I realize that this article has by no means covered every aspect of REST, but I hope it fills a gap that I felt as I was learning all of this.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Christian Sepulveda

Don't Underestimate the Power of Laughter

Christian Sepulveda
Thursday, May 24, 2007

Do you laugh everyday at your job? If not, why? I think too many people become
complacent at their job and accept being bored, frustrated or just generally not
happy.

Laughter is not the only benchmark though. I think you should also ask, “Did I
learn something today?”.

I am not advocating resignation on the first laugh-free day nor should the work
environment become a comedy club or a playroom. But I want employees who take
their own professional development and satisfaction seriously and demand a “yes”
to both questions. It is a character marker of the employee and one of the
organization.

I’ve worked in situations where I could answer yes in some cases and no in
others. While obvious, I can’t overstate the difference for my own productivity
and general mental health when I could answer yes. And don’t assume you have to
be lucky to either structure such an organization (for the employer) or find one
(for the employee). The companies are out there and if you can’t change your
organization to accommodate such satisfaction, then what can your organization
do?

These two simple questions are a good litmus test assessing your current
employment, or for the employer, the quality of your work environment. I suggest
asking the question every day over the next week and then review your answers.

So, did you laugh today? What did you learn today?

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Joe Moore

Standup 05/23/2007

Joe Moore
Wednesday, May 23, 2007

Interesting Things

  • Some projects are playing with the Mocha mocking framework. From their site:

    Mocha is a library for mocking and stubbing using a syntax like that of JMock, and SchMock. Most commonly Mocha is used in conjunction with Test::Unit, but it can be used in other contexts.

  • Our own Nathan Sobo has released Treetop 0.1.0:

    Treetop is a Ruby-based DSL for text parsing and interpretation. It facilitates an extension of the object-oriented paradigm called syntax-oriented programming.

  • Jeff from Inveneo presented us with a tech-talk recently about the technology they are bringing to rural and remote communities throughout the world. Fascinating stuff. A group here has volunteered to help write some software if needed.

Ask for Help

  • “Are there problems getting Rspec mocks to ‘reset’ for each spec run?” Mocks persist across test/spec runs for class methods, so watch out.
  • “My routes arn’t working…” Remember that Rails routes are positional, which means that they are matched top-to-bottom; changing the position seemed to be the fix in this case.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Joe Moore

Standup 05/22/2007

Joe Moore
Tuesday, May 22, 2007

Interesting Things

  • We are hosting a Geek Session tonight at SF Beta. Tickets are going fast.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Edward Hieatt

Taming JavaScript in practice: event handlers

Edward Hieatt
Tuesday, May 22, 2007

Suppose we have some behavior attached to a button’s onclick event: when clicked, the button should append “foobar” to the value in the text field with ID “output_field”. We might do it like this:

<input type="text" id="output_field">
<button onclick="var textField = document.getElementById('output_field'); var currentValue = textField.value; textField.value=currentValue + 'foobar';">

Inline event handler code such as this is extremely common. It’s easy to write, but it’s not testable, reusable, or readable, and it’s mixed up in the HTML world. The way it is currently, it’s hard to think of it as code that can be refactored, added to, abstracted, generalized, etc. Of course, this is a contrived, simple example, and if it were real code, probably not worth worrying too much about. However, we can use it to demonstrate some techniques that we can apply to real-world situations.

Extracting the handler to a function

Let’s attack it by considering it from the point of view of testability with JsUnit; very often this can the best way to move forward because it creates a second client to the code that is relatively independent of the HTML DOM. The first step is to extract the onclick event into a function, rather than having it inline:

<script language="javascript">
  function appendFoobar() {
    var textField = document.getElementById("output_field");
    var currentValue = textField.value;
    textField.value = currentValue + "foobar";
  }
</script>

<input type="text" id="output_field">
<button onclick="appendFoobar()">

Notice that even ignoring testability, this is a dramatic improvement. First, we don’t a fragment of JavaScript floating around in an HTML element. Second, we have a name for our behavior (appendFoobar) that makes the code more readable: it’s now much clearer that clicking the button should write the current date. Third, we can now reuse this code from more than just our onclick handler.

Writing a test page

The second step is to move our function to an external .js file, say appender.js, so that we can write a Test Page:

<script language="javascript" src="appender.js"></script>

<script language="javascript">
function testAppendFoobar() {
  assertEquals("initialvalue", document.getElementById("output_field"));
  appendFoobar();
  assertEquals("initialvaluefoobar", document.getElementById("output_field"));
}
</script>

<input type="text" id="output_field" value="initialvalue">

Our test is for our extracted function: our test, rather than the button element, calls our extracted function.

Injecting DOM dependencies

Now that we have a green test, and code that we can actually read, we might want to consider the following refactoring. The code and test both go out and grab an element from the DOM with a certain ID. The code would be more self-contained and reusable if rather than going out and finding the DOM element, we instead passed it in to appendFoobar. That is, we could inject the dependency on the DOM element:

function appendFoobar(textField) {
  var currentValue = textField.value;
  textField.value = currentValue + "foobar";
}

function testAppendFoobar() {
  var textField = document.createElement("input");
  textField.value="initialvalue";
  appendFoobar(textField);
  assertEquals("initialvaluefoobar", textField.value);
}

<button onclick="appendFoobar(document.getElementById('output_field'))">

Extracting an object

Let’s do one more refactoring: objectifying our code. Obviously, at this point our simple example doesn’t warrant this refactoring, but let’s keep going to illustrate the point. We’ll use prototype.js to keep things simple:

Appender.prototype = {
  initialize: function(textField) {
    this.textField = textField;
  },

  appendFoobar() {
    var currentValue = this.textField.value;
    this.textField.value = currentValue + "foobar";
  }
}

function testAppender() {
  var textField = document.createElement("input");
  textField.value="initialvalue";
  var appender = new Appender(textField);
  appender.appendFoobar();
  assertEquals("initialvaluefoobar", textField.value);
}

<button onclick="new Appender(document.getElementById('output_field')).appendFoobar()">

Summary

Our code has come a long way from being an inline event handler, muddled up with HTML code. In its new form, it’s the kind of code that many developers are more comfortable working with. By aggressively refactoring even simple event handlers with these techniques, we can make working with our JavaScript a far more pleasant experience.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Rails Conference Links

Alex Chaffee
Monday, May 21, 2007

(Blabbers who were at the conference, feel free to add your links to this post.)

  • Alex’s RailsConf2007 Flickr set
  • railsconf2007 Flickr tag (notice all the band pix :-) )
  • Parker’s Flickr Set
  • Martin Fowler’s bliki post on RailsConf
  • Tim Bray on the band
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Joe Moore

Standup 05/21/2007

Joe Moore
Monday, May 21, 2007

Interesting Things

  • Rails gotcha: with ActiveRecord.findXXX, you can specify query parameters such as :group_by, :limit, and :include. But if you use those three together Rails will generate an incorrect query.
  • Rspec 1.0 has been released.

Ask for Help

*“Can you use the Venkman Javascript Debugger to debug programatically-loaded JS, files that are actually hosted by a 3rd party, such as Yahoo!?” We don’t think so, but if anyone in the community has an answer, let us know.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Beer Night PDX

Alex Chaffee
Saturday, May 19, 2007

front
back

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Topics

  • agile (778)
  • rails (113)
  • testing (86)
  • ruby (83)
  • ruby on rails (70)
  • jobs (62)
  • javascript (53)
  • techtalk (44)
  • rspec (38)
  • activerecord (29)
  • productivity (29)
  • gogaruco (29)
  • ironblogger (29)
  • git (28)
  • nyc (27)
  • rubymine (25)
  • mobile (21)
  • cucumber (20)
  • bloggerdome (19)
  • process (19)
  • pivotal tracker (19)
  • design (18)
  • jasmine (18)
  • ios (18)
  • webos (17)
  • objective-c (17)
  • android (16)
  • palm (16)
  • "soft" ware (16)
  • fun (15)
  • tracker ecosystem (15)
  • ci (15)
  • cedar (15)
  • rails3 (14)
  • performance (14)
  • gem (13)
  • bdd (13)
  • selenium (12)
  • css (12)
  • goruco (12)
  • bundler (12)
  • tdd (12)
  • meetup (11)
  • railsconf (11)
  • nyc-standup (11)
  • capybara (10)
  • mac (10)
  • mojo (10)
  • chef (10)
  • rubygems (9)
Subscribe to Community Feed
  1. 1
  2. 2
  3. 3
  4. →
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >