Archive for the 'Ruby on Rails' Category

Intro to Rails (using v. 2.0)

Friday, December 7th, 2007

Larry LOVES Ruby on Rails

As some of you know, when I’m not working I’m taking classes in Information Systems at UCF. One of the classes I took this semester was Web Systems II, which is essentially a server-side course that focuses on ASP.NET development.

One particular assignment was creating a “Category Code Manager”, which I had never heard of previously. I think the professor made the term up, but the concept is simple nonetheless. There are categories (ie: fruits) that each can have many codes (ie: apples, oranges). I think the purpose of the assignment was to get used to working with foreign keys, and building dynamic drop downs as a tool to display this sort of relationship. Another gotcha is that the categories can have parent categories.

The class had a participation grade that I must have overlooked… Needless to say that didn’t bode well for me, so I created this screencast as an introduction to Ruby on Rails (beginner level) using the new Rails 2.0 (final source code included.) I tried to follow best practices where possible (ie: TDD), and covered the topics of:

  • Database agnosticism & environments
  • Using rake to create databases, and to run
  • Scaffold generator
  • has_many & belongs_to relationships within ActiveRecord
  • The interactive Rails console
  • The new integration of the ruby debugger, and a drop of live metaprogramming
  • Test Driven Development with Test::Unit
  • Intro to REST’ful architecture within Rails

But, I left some things out to avoid making the screencast even longer, and avoid it being confusing for beginners. Just so you all know, some changes I would have made include:

  • Create some helper methods for things like populating the select tags
  • Use nested routing (I did this first, but renaming all the named routes, having to explain the routing, etc made this too complex for a beginner video)
  • Use RSpec for testing (RSpec’s scaffold uses mocks and stubs, which are just a little too much to explain when already introducing all of Rails and testing)
  • Use a REST’ful abstraction plugin (we developed an internal one at work, but unfortunately we haven’t been able to open source it yet… until then check out make_resourceful)
  • Use the ObjectMother pattern for creating objects during tests

Enjoy the screencast!

Rails controllers are proper resources

Thursday, August 9th, 2007

I’ve been doing a lot with REST and ROA on and off the job lately (mainly with Eric and Dray, who still does not have a blog.)

The way Rails implements resources is through Controller classes. One thing that came up yesterday, was the argument that the implementation is improper due to the inclusion of both an index and a show action in one Controller. In REST, a resource can be its own entity (ie: an apple), or a collection of of entities (ie: a fruits resource composed of apples, grapes, oranges, etc.) At first glance, the challenge to Rails Controllers seems to stand because a GET to the index action returns a collection of resources, whereas a GET to the show action just returns one resource.

Upon closer inspection though, you’ll see that the confusion comes from focusing on Controller actions. What should really be looked at is the resource (the controller), and how those two requests are addressed (the URI.) Firstly, notice what kind of resource we have… it’s a fruits resource. Next, look at the URI, it is /fruits.

Now that we’ve established that our FruitsController represents a plural resource (a collection of fruit resources), we can move on to explaining the confusion that the index and show actions introduce. A request to /fruits will return all of our fruits. But, the world has many fruits and we don’t want to request them all. Instead, we will fire a GET at /fruits?page=2?limit=10. Although most of you will recognize this as simple pagination, in ROA it is known as the concept of addressibiliy to indicate state in the URI.

Here’s where the confusion is cleared: a request to /fruits/1337 is not requesting a singular resource (in this case a cherry, the most elite of all fruits.) Instead, it is requesting a collection resource (fruits) but using addressibility to indicate state. It is okay to use the URI in REST different ways for addressiblity, because REST is a style and does not have a specification for addressing via URI’s. For example, another way of getting to /fruits/1337 might be /fruits/?page=1337?limit=1.

As a closing note, even though we used the fruits resource collection here and addressed cherry, we could have done it differently still. If you really wanted a singular cherry resource, you can do so in routes.rb by replacing map.resources :fruits with map.resource :cherry (notice that “resource” is singular.) This would map to a singular CherryController to implement the resource. You could access it with a get request to /cherry, which would map to the show action (in this case the index, or list, action does not make sense because cherry is singular.)

The Best Thing About Rails is the Community

Tuesday, May 22nd, 2007

Wow… RailsConf07 was absolutely amazing. The interesting thing is that I am not talking about the presentations, although they were top-notch. Instead, the Rails community is what made this conference so… heart-touching, even.

Rails is Love

Chad Fowler directly announced that he picked the keynotes and sessions as his personal mold for what we should be thinking about. To this end, I thank him deeply for his choices.

While there, I came to recognize the Rails community in a new light. I don’t think I could have understood this unless actually being there either (as cliche as it sounds.) Our community stereotype as elitist, arrogant developers did not show its face.

I hope that the community stays like this, and that everyone has a chance to go to at least one conference like this.

RailsConf Crowd

All of the attendees were teeming with positive energy and friendly. The diversity of people was great, including people from different states and countries, and people in suits (maybe one or two) to people dressed like hippies and supermodels (you can guess here…). Breakfast and lunch was served in an enormous open room full of tables and seats. But, everyone there was inviting, and immediately started conversations naturally. This was true of people in the hallways too, and included speakers and even DHH himself. Chad even told us to introduce ourselves to somebody new during one of the breaks, although this was happening naturally anyway.

The ad-hoc organization of lightning talks and RejectConf led to some of the more interesting demonstrations. Similarly, post-session conversations with speakers that led to group discussions, which then led to BoFs ,fully capture the spirit of the conference. The BoFs in general stood on their own as hallmarks of open, informative discussion… not just presentation.

Each day opened with one of the hilarious Mac VS PC spoofs by Gregg and Jason. Keynotes were accompanied by accordion and ukulele (courtesy Joey deVilla and Chad Fowler, respectively), and even a spoof serenade (to the tune of ) to our beloved creator DHH.

DHH stressed the importance of plugins both as a community way to share common functionality and testing-grounds for Rails core-features.Avi Bryant (creator of Seaside) gave a jaw dropping and eye opening talk exposing similarities between Smalltalk and Ruby. He strongly recommending stealing from Smalltalk’s maturity in IDE and especially VM implementations. Specifically, a highly distributed virtually machine network by a local Portland company called Gem
Stone. Supposedly, converting this to Ruby would not be overly difficult. But, it would make Ruby run as fast as Smalltalk, which is approximately 10 times faster than Python (and 3 to 4 times slower than Java).
Besides that, Avi stressed his belief that state is good, and that like wine, “objects get better with time”. In his opinion, that is the path that Ruby should follow, effectively becoming Smalltalk =p. This was not a unique opinion though, as Chad seemed to support Smalltalk. As a bit of comic relief, Avi introduced himself as “from the future” and had a hilarious metaphor from 2001: A Space Odyssey (we are the apes…)Smalltalk VS Ruby

Dave Thomas even attacked the browser with its transition from form based requests to AJAX as a medium for the web. He compared it to a similar evolution of ideas that happened in early computers, and warned to not get stuck in a loop of repeating history. Dave went on to get the audience to come up with more examples of this “cargo cult”, evoking responses as extreme as REST, Mongrel, and Rails itself. Although, he did boldly reject the idea that conferences could ever be a cargo cult =p.

Dave Thomas had a donation-based all day tutorial that raised over $12,000 by itself. After witnessing this accomplishment, Chad Fowler (and many other speakers that followed) encouraged the audience to continue donating throughout the conference. Eventually, a challenge to make this the standard for tech conferences was put in place. It is still going on, so anyone is still encouraged to donate.

As a whole, RailsConf07 was one of the most spectacular things I’ve ever experienced. There were many other interesting things happening, such as the effort to understand how “the enterprise” will fit into Rails, and various thought provoking sessions. But, by far the Rails community showed that it is concerned, responsible, and innovative, and I am extremely proud to be a part of it. If you were there, please take the time to blog your version of the event (and encourage others to do so as well) so the rest of the community can understand what is happening and share the excitement.

Beast Source Code Snippet

Wednesday, April 18th, 2007

I downloaded and browsed the source code for the Beast forum today. Because it’s REST’ful, open source, and developed by Rick Olson, I recommend any Rails developer to look at it. What makes it even better is that a goal of Beast is to “stay around 500 lines”, meaning the app doesn’t take much time to figure out and can be studied leisurely.

Anything you define in YourController#rescue_action will be run when an error is raised, so check out what I found in Beast:

def rescue_action(exception)
exception.is_a?(ActiveRecord::RecordInvalid) ? render_invalid_record(exception.record) : super
end

def render_invalid_record(record)
render :action => (record.new_record? ? ‘new’ : ‘edit’)
end

As you can see, now any errors that are invalid AR objects will call a special method. This method render’s new or edit depending on whether the record exists yet or not.

So…rather than doing this in our controllers:

def create
@record = Record.new(params[:record])
if @record.save
flash[:notice] = ‘Saved successfully’
redirect_to :action => ‘index’
else
render :action => ‘new’
end
end

We simply do this:

def create
@record = Record.new(params[:record])
@record.save! and flash[:notice]=(’Saved successfully’) and redirect_to(:action => ‘index’)
end

The magic is in the save! method, as the “bang” raises errors instead of returning false when validation fails, not bad!

On another note, I’ve been spending a lot of my time recently on reading books about and developing a social site… As you know, my ambition to blog a lot since the creation of larrytheliquid.com has quickly diminished. I’m making this app to change that for myself and all bloggers… but that’s enough for now =)

Validating Positive With Infinity

Sunday, March 18th, 2007

Ruby has a nifty feature to be able to use a special constant that represents infinity, accessible as follows:

irb(main):001:0> 1.0/0
=> Infinity

Recently, I needed to validate that a field in my Rails model would be positive. While there are countless ways to do this, I was very happy to find a fun and practical use for infinity.

validates_inclusion_of :some_attribute, :within => 1..1.0/0, :allow_nil => true, :message => 'should be positive'

The attribute is validated to be within positive one (inclusive) and positive infinity (technically exclusive.) This is done with Rails’ validates_inclusion_of for numeric data, Ruby’s range operator .., and the infinity constant 1.0/0.

Huzzah!