Showing posts with label rails. Show all posts
Showing posts with label rails. Show all posts

Wednesday, December 10, 2008

Ruby on Rails 10 Tips - Part 1: Development


I was recently asked by some colleagues for advices and best practices developing, securing, and deploying Ruby on Rails applications. While I don't have full fledge best practices, I do have lots of tips to share. These are not as thorough as best practices or well structured as patterns, but are instead short, to the point, common knowledge and not so common knowledge that I found useful in my experience developing Rails applications.

Also, most of these tips come from my either my own experience, discussion with others in the community at Meetup and RailsConf, as well as reading various blogs and books on the subject. I apologize in advance if I have not linked to your blog where you have similar tips. Feel free to leave a comment and I will do so.

Finally, I love a great debate. If you disagree with any of these tips then by all means post a comment and let me know what you disagree with and why. I know at least one colleague at IBM Research, Chet Murthy, who is experienced in Rails development and disagrees with me on at least one of these tips. I welcome your feedback Chet.

Enjoy!

10 Rails Development tips

  1. Use ActiveResource and avoid ActiveWebService. With ActiveResource and multiview support in Rails 2.x you can easily expose RESTful models as well as Atom/RSS feeds on these models as well as JSON and any other view format you can wish for.


  2. Consuming ActiveResource is easy by using self.site = "URL" in the client side. However, that does not add data to the DB and every query will result in a REST call. Caching data is key.


  3. Use Rake to automate any other tasks you do. Custom Rake tasks are easily added in lib/tasks. Use $rake -T to see current tasks available, including yours.


  4. Use database migrations to update models once your design is solid and you have a first release and cannot avoid data losses. That is, to be clear, use one migration per model early on and then once app is released for beta, every change to the models should be via new migration (not an update to the old migration). This will save lots of headaches in future and allow you to easily move application from one version to next one.


  5. Use Solr vs. Ferret for models searchability and associated acts_as_xyz plugins. This is due to the fact that Ferret indexes tend to get corrupted. This, in some sense, is a shame since Ferret is a nice and easy plugin.


  6. Make sure to use Rails validations in your models. I would avoid special DB statements in migration code. This makes it easier to move to different DB, e.g., MySQL to DB2.


  7. Use view partials to keep your views DRY. Essentially, partials should be any view code that is repeated, similar to a subroutine call (PullUp or PushDown method refactoring). Use a app/views/shared directory for partials that are across controllers. Also, always use the controller (or shared) name when calling the partial. This will help you avoid view errors when refactoring views into shared.

    So instead of:



    do instead


    When not specified the controller is assumed to be the one from the calling view. If you reused funky_partial in a view coming from a controller other than my_controller, you will get a view partial file not found exception. Easily fixed but easily avoidable as well.


  8. Don't add new actions to ActiveResource models, other than the basic CRUD operations' actions. Instead use a separate controller that groups actions related to one or many ActiveResources, e.g., don't add login/logout action in User model if that's an ActiveResource, and so on. This is because you will need to add special routing maps in your config/routes.rb and that will be hard to maintain. ActiveResouces are RESTful by design and the actions added with scaffold are good enough. Use $rake routes to see all your routes (more on this point later).


  9. Refactor common code as plugins after you notice it being used many places and applications. This is especially true for moving common model code into acts_as_xyz. This is harder to do when you first start but becomes easier after a few apps and you have done one. See this RailsOnWave tutorial for a intro guide to creating your own acts_as_xyz plugins


  10. Tests, test, test. Whether you test first or test last or in between, in many ways what matters is the fact that you are testing. Doing TDD means having some sustained development flow that always include tests. If your code base is growing one sided (that is tests are not growing in same rate as code) then something is wrong and you will pay for it in the future. Use $rake stats to get a feel for your current code/test levels.


Next I'll list my top 10 list of tips for Rails application deployments and scaling.

Monday, March 31, 2008

A geeky but fun week-end



I am co-organizer of SDForum's 3rd Silicon Valley Ruby conference. It will easily be the best conference for all things Ruby and Rails in the valley this year and likely the best such gathering outside of Portland (RailConf 2008) and Salt Lake City (RubyConf 2008).


The line-up of speakers includes emerging applications of Ruby and Rails by startups, esoteric applications by academia, as well as mature enterprisey companies seeing the "light" and supporting the community. As quick a sample, we will have technical presentations by:

Like last year, the conference happens in the San Jose Tech Museum of Innovation starting Friday April 18th and continuing Saturday April 19th.


Come learn what folks are doing with Rails and Ruby. However, let me forewarn you that If you are still deciding what platform to use to create your new Facebook or OpenSocial application _OR_ your new Web 2.0 startup _OR_ your next enterprisey project, attending this conference could result in a no-brainer decision...

Hope to see you there!

Sunday, February 24, 2008

The prospect of Ruby and Rails

Andrew McAfee on Enterprise 2.0

I recently attended a talk by Andrew McAfee (Harvard Business School) at the famed Palo Alto Research Center (PARC). Andrew is one of the more eloquent speakers from business schools on matters of technologies. His talk at PARC was on Enterprise 2.0 or how the recent evolution of the Web is infiltrating inside enterprises and what enterprises can do to take advantages of new Web innovations.


Andrew McAfee at PARC on 21 February 2008. Credit, self with iPhone

While Andrew's talk was delivered passionately, most of what he discussed was not new to me, and I imagine not new to anyone monitoring the valley or Web 2.0. However, Andrew mentioned one thing that caught my attention and made me decide to post this entry...

Prospect Theory and TiVo

After discussing the various ways in which Web 2.0 is impacting enterprises, e.g., blogs, wikis, social networking, and virtual markets, Andrew highlighted some challenges that still remain. In particular, he explained that Web 2.0 technologies will only slowly become mainstream in enterprises. This is because, in most decision makers' minds, Web 2.0 innovations are not 10x (or more) better than current alternatives. The 10x figure is not magic, it comes from Prospect Theory.

Developed by Daniel Kahneman (Princeton University and Hebrew University) and Amos Tversky (1937 - 1996), Prospect Theory (PT), for which Kahneman would win the Nobel prize in economics in 2002, tries to explain the psychology of decision-making of agents that are faced with deciding between alternatives in the presence of risks. In particular the theory tries to explain an agent's decision-making in the face of the prospect of "better" alternatives (B).

One interesting result of the theory, confirmed many times empirically, is that when agents are faced with the decision to move (or change) to alternative B from a known, workable alternative (A), they tend to overestimate alternative A as being three times better than what it is and at the same time underestimate the prospective B as being three times less valuable than what it is... This implies that in order for alternative B to become mainstream (thereby displacing A), assuming no additional changes to the market and rounding the numbers, the new prospect B should be at least 10x more "valuable" than the alternative it is displacing, i.e., A.

Andrew explained that the 3x figures are supported by various empirical data drawn from many experiments. He illustrated his point by making a quick (unscientific) poll with the audience. He asked who had, loved, and evangelized TiVo. Interestingly, about 10 to 15 percent of the audience raised their hands and never let it down... The point is that while TiVo has a good, passionate, following, however, it is not generally seen as being 10x better than current TV experience, and thus is not causing a mainstream change in current TV viewers.

I am not an economist, but I immediately saw the importance of Andrew's point and how he may be right applying PT's results to the infiltration of Web 2.0 tools into the enterprise. I also quickly thought of applying the same to one of my research area: Web computing.

The future of Web programming

Web programming has evolved from CGI scripts written mostly Perl, to server-side applications running on complicated containers written in Java and .NET, to now increasingly using various agile and lightweight server-side frameworks using dynamic scripting languages such as JavaScript, Python and Django, Project Zero, and Ruby and Rails. This evolution is not accidental, but rather, I believe the result of the need for agile reaction to changes in requirements for such applications as well as the new complexities of Web applications; and finally the increase performance of networks and of the devices that we are using to connect to the Web.

It is well documented that individual and teams of programmers can quickly build Web 2.0 Web sites in Ruby on Rails much faster than they can with Java EE or .NET or Perl. Naturally, there will be cases where this productivity is not applicable, say areas where lots of legacy code is to be reused, or where skilled programmers cannot be found, or where scalability (to many millions of concurrent connections) is required. However, on average, it is fair to assume that building Web applications using modern scripting frameworks, such as Rails, allows a huge advantage to programmers.

The DSL hypothesis and the prospect of Ruby and Rails

The way to understand this increase in productivity, I believe, is in what I call "the domain-specific language (DSL) hypothesis." Dynamic languages, especially Ruby, allows the creation of libraries and mini-languages (DSLs) that allows one to represent domain-level concepts in a way that they can be programmed directly. For instance, in Rails programmers can represent the data model of their application using the ActiveRecord DSL. Using ActiveRecord constructs, programmers directly represent the relationships amongst the models and their "shape". Using metaprogramming the constructs are translated into code that is executed by the framework and the underlying database. This meta-level expression capability saves the programmers a huge burden and increases her productivity.

However, while these dynamic languages and DSL are increasing productivity of programmers everywhere, they are not making as much inroads into enterprises... Why is that? Maybe Prospect Theory is the answer; or maybe, we are just too early in this wave change and we need to give enterprises and enterprise programmers more time to catch up with the rest of the community. I don't have enough evidence to suggest that languages and frameworks like Ruby and Rails provide 10x increase in productivity over Java EE or .NET, but from my own experience I believe the figure is close...

To help make my point and to encourage naysayers to look seriously into these alternative Web computing paradigms, I have created a list of 10 reasons Why I love Ruby. I posted reason #1 last year and promised to continue posting the subsequent ones over the next few months. I am not claiming that together these reasons will prove that Ruby and Rails will become mainstream, however, I hope they will encourage enterprise programmers to give strong considerations to trying these alternative paradigms, as I believe once they get a taste of the productivity boost, they will raise their hands like these TiVo passionate in Andrew's lecture.

Change log
24 February 2008 - first posted

Sunday, November 18, 2007

Why I love Ruby? Reason 1: because strings change and when manipulated should stay strings and be readable


Why strings are critical
Many modern languages come built in with string libraries or better with strings as a first class concept. Arguably, languages that have not done so have suffered significantly from that shortage; case in point C++ which, in the early 1990's, saw a variety of string libraries from vendors fighting for dominance, while the language itself became less relevant and surpassed by better alternatives.

The issue may on the surface appear to be unimportant, however, in practice having excellent string support in a language is hugely critical. Most tasks involve some type of string manipulation or usage, e.g., file input and output, strings as keys to hashes, and for user interface, just to name a few. This simply implies that a language that facilitates strings manipulations results in a real productivity boosts for programmers. In the case of Ruby, as I hope to convince you, the string support is so comprehensive and advanced that the common string tasks become a breeze, but also have a nice side effect of keeping the code rather readable.

Basics
The Ruby designers have chosen to make strings a first class type and the language includes a comprehensive library supporting strings. Unlike some other languages, strings in Ruby are mutable. This means that strings, when manipulated, do change and do not result in unique copies---Ruby has the concept and basic type of symbols that can be used for that that purpose. This decision has interesting consequences, though let's look into the basic string type usage and implementation in Ruby. The following Ruby code snippets illustrate the usage:

s = "this is a string" # creates a string
s += ', and this is another' # shows that strings are created with double or single quotes

The built-in String class contains tons of methods and also includes various modules (more on that in a future WILR Reason) that provides enumeration, comparison, and partitioning. Some basic methods:

s.capitalize # => "This is a string" as a new string
s.capitalize! # same result but modifies the receiver

s.upcase # => "THIS IS A STRING" (a new string)
s.downcase # => "this is a string" (a new string)

s.split # => ['This', 'is', 'a', 'string'] as an array of the elements
s.split('is a') # => ['This is ', ' string']

s.gsub! 'is ', '' # => "Tha string"

NOTE: s is modified to new value, Ruby idiom to use ! for methods with side effects

Advance manipulations

s.include? 'is' # => true
s.include? 'Is' # => false

s.insert 9, 'nother' # => "This is another string"
s.replace 'string' # => "string" (modifies string s)
s.center 20, '_' # => "_______string_______"
s.squeeze # => "_string_"
s.crypt 'password' # => "paHjoO.AYUKRQ" (one-way cryptography)

There are also various methods for matching with regular expressions, e.g., String#match, String#grep, and String#scan . I'll discuss them in a future WILR Reason since regex support is one of the reasons :-)

Features
Perhaps the most interesting and powerful aspect of Ruby strings are their support for having inline statements and the ease in which multiline strings can be defined and created.

a_string = 'cool'
"this is a #{a_string} string".capitalize! # => "This is a cool string"

x, y = 22.0, 7.0
"#{x}/#{y} = #{x/y} is an overestimate approximation for Pi which is closer to #{Math::PI}" # => "22.0/7.0 = 3.14285714285714 is an overestimate approximation for Pi which is closer to 3.14159265358979"

Creating multilines strings is as simple as:

s1 = %{Ruby on Rails
A clean, agile, and powerful Web framework
Created by David H. Hanson at 37signals}

s2 = <<END_STRING
Ruby on Rails
A clean, agile, and powerful Web framework
Created by David H. Hanson at 37signals
END_STRING

s1 == s2 # => false since s1 does not include the last newline
s1 += "\n"
s1 == s2 # => true

Final thoughts
As you can see, Ruby's String support is comprehensive and very easy to learn. The String class comes also built in with enumeration and comparable features. These aspects allow strings to be used like any other enumerable data types (e.g., arrays and lists) and also be compared for sorting and other comparison-based algorithms.

Because strings are mutable implies that the Ruby virtual machine can make efficient allocation for String instances. This is in sharp contrast to the Java programming language, for instance, which mandates immutability of strings and where multiple copies of strings with the same value can eat at the heap space.

Finally, the fact that strings can have embedded statements and creating multiline strings in Ruby is so easy has an interesting side effect when doing metaprogramming. In a nutshell, with some careful usage the metaprograms can be as readable as the code that they are representing. More on this in a later WILR Reason.

Tuesday, October 30, 2007

Why I love Ruby?

Since I am a vocal advocate of the Ruby programming language and the various tools, frameworks, libraries, and domain-specific languages (or DSLs) that are mushrooming around it, I often am asked to explain the difference or similarities between Ruby and other languages, e.g., Java, Python, PHP, and so on; or simply people often asked me simply why I so vocally advocate Ruby?


To make it easy to answer such questions and shed some lights on the matter, I decided to aggregate my answers and refine my thoughts into a series of blog entries that attempt to shed light summarize the technical reasons and give you my personal views as to why I am such a fanboy of the Ruby programming language and of the grassroots movement that accompanies it.

(photo credit: http://flickr.com/photos/19414947@N00/818191499/)

I hope this will be a conversation over the next months or so, and while I have at least 10 prepared reasons (posts) to answer this question, I plan to unveil them every other day week (or so) and refine them with real code examples or pointers.

I would love to hear your thoughts on the subject, so please feel free to add comments --- views in agreement or violent descents are welcome equally.

So without more introduction, here is why I love Ruby and why I think it is a programmer's and software researcher's best friend.

Minor updates on 11/18/2007