Tuesday, February 27, 2007

Two More Thoughts

My buddy Anthony collected some of his Thoughts About Work. Good list. I wanted to add two more.

* Surround yourself with people you can learn from and have fun with.
* Share both your successes and failures with your team. Everyone can learn from both.

Tuesday, February 20, 2007

A Way To Add Trust To OpenID?

Thinking about OpenID, the next step is obviously a way to integrate trust into an identity. The first question people will want to ask, I believe, is, "Is this person a spammer?" (Insert your own definition for spammer here, but typically this will mean "Will this person use this site/application/service for the originally intended purpose and will abide by the policies and rules of the site/application/serivce?")

Now that it seems like everyone is getting on board with OpenID (AOL, digg, Technorati, LiveJournal, even Microsoft), there are a lot of identities swimming around. This is a Good Thing. However, nothing stops a spammer or Bad Guy from creating their own OpenID. This is also a Good Thing, because OpenID is only there to verify the identity. Other technologies and layers are then free to add in Trust.

There's a lot of built up trust information out on the web if we can just get to it. Think about all the hard earned feedback profiles and rankings you've amassed over the years. Some examples might include:

* eBay
* slashdot
* digg
* epinions
* amazon (product comments and ratings)
* amazon marketplace
* technorati
* your Google PageRank?

If there's a way to integrate my identity with my profile on these sites, I could build an aggregate of my Trust Rating. If you trust eBay's trust rating, and I have a high rating, then you could trust me. It's trust by proxy, and the entire SSL infrastructure runs on this.

Over time, each of the mentioned services will offer an OpenID. So we'll need a way to be able to assert that all those identities are views of the same entity (person, in this case). Second, we'll need a way to convey whatever ranking or profile each identity has with each service. Third, and optionally, it would be very nice to somehow create a TrustRank given all those statistics.

Services like eBay and Amazon won't only be OpenID providers, but also over time will become OpenTrust providers.

Semantic Web technologies that might help to make this happen:

* OWL with its owl:sameAs, to assert that all my identities are effectively "me".
* A simple RDF vocab with OWL rules for expressing my ranking on a particular site.

Thursday, February 15, 2007

Java Might Get a Formal API for REST. Even Needed?

Henry Story has a great rundown on JSR-311: a Java API for RESTful Web Services?. Lots of links for REST APIs and implementations and frameworks for Java.

Is a REST framework for Java even needed? I think a better Servlet and HTTP library would serve a better purpose, allowing Java to be more RESTful while at the same time making programming HTTP easier and more explicit.

Wednesday, February 7, 2007

Refactoring REST: searching for an abstraction — Luke Redpath

Luke Redpath makes a valiant attempt to DRY up RESTful Rails controllers as he writes Refactoring REST: searching for an abstraction. I can see how this can be very useful if your controller methods follow the simple paths. Good to see some implementation patterns emerge that build on the assumptions that your controller is RESTful.

Sunday, February 4, 2007

The Machine Is Us

Sit back, enjoy, and get pumped up for building web applications again.





Friday, February 2, 2007

ActiveWarehouse at RailsConf

My buddy Anthony Eden is presenting at RailsConf 2007. He'll be talking about Data Warehouses on Rails with ActiveWarehouse.

I'm currently building a Data Warehouse fronted by Rails, and some of the code I've written has ended up in ActiveWarehouse. It's a really interesting project, and I hope to see it bring data warehousing into every application.

I'll be at the talk, hope to see you there!

Thursday, February 1, 2007

Rails, Collections, Forms

I just figured out how to handle collections of unsaved ActiveRecord objects in XHTML forms rendered by Ruby on Rails, so I thought I'd share with the hopes of making the next person's search a bit quicker. Note: This post assumes you have Rails 1.2 and are generally following RESTful principles and are using `map.resources`. The main concepts work without `map.resources` but you'll have to tweak some of the URLs.

The problem: You have a collection of unsaved (new) ActiveRecord objects that you would like to render fields for in the same form. For instance, you want to let a user enter multiple phone numbers before they initially save the User object and its collection of PhoneNumber instances.

Solution: Turns out, Rails makes this pretty easy (but of course) but the hard part is just figuring out how. We'll assume you have a controller method that initializes the user and a phone number. We'll start with a single phone number just to make things easy.

[sourcecode language='ruby']
def new
@user = User.new(params[:user])
@user.phone_numbers << PhoneNumber.new
end
[/sourcecode]

Let's first create the partial for the phone number fields. We make a partial because there can potentially be multiple phone numbers for a user, so this will keep things DRY.

[sourcecode language='html']

<% fields_for 'phone_numbers[]', phone_number do |f| %>


<%= f.text_field :area_code, :index => phone_number_counter %>



<%= f.text_field :number, :index => phone_number_counter %>

<% end %>

[/sourcecode]

Notice the 'phone_number_counter' variable? And the ':index' symbol inside 'f.text_field'? We'll get to those in a moment, but they are key to making this whole thing work.

In your 'new.rhtml' file, you'll need something like this:

[sourcecode language='html']

<% form_for :user, users_url do |f| %>


<%= f.text_field :name %>

<%= render :partial => ‘phone_number’, :collection => @user.phone_numbers %>
<% end %>

[/sourcecode]

If you've never seen `render :partial, :collection` before, go read up on it from the docs. It's very handy.

The first time you render the page, you'll see something like this (edited for clarity):

Name:

Area Code:

Number:

When you submit the form, your controller can handle the params as such:

[sourcecode language='ruby']

# POST /users
def create

@user = User.create(params[:user])

params[:phone_numbers].each_value do |phone_number_params|
    @user.phone_numbers << PhoneNumber.create(phone_number_params)

end
end

[/sourcecode]

Summary: When create new instances of objects from a form in Ruby on Rails, use `render :partial, :collection` to easily loop through your collection, rendering the partial once for each item in the collection. Inside your partial, you will receive (for free!) a counter variable to let you know which iteration you are rendering. You can then use that counter as the unique identifier for your form fields. Once your objects are saved, though, they will have IDs and thus you won't need to consult the counter for an identifier.

In fact, Rails makes that scenario drop dead easy. If your objects in your collection have IDs, then just leave out the `:index` symbol from your form field builders. Just by placing `[]` at the end of your form fields identifier (as we have above with `phone_numbers[]`) is enough to tell Rails to use the ID from the object when rendering. But again, if your objects are unsaved, you must specify `:index` as we have in the above example.

ps: Is there a better way to do this? Please, let me know!

Disclaimer

I'm probably required to say that the views expressed in this blog are my own, and do not necessarily reflect those of my employer. Also, except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 3.0 License, and code samples are licensed under the BSD License.