Showing posts with label Ruby. Show all posts
Showing posts with label Ruby. Show all posts

Saturday, July 28, 2012

Deploying on TV screens

Off late, I am working on a project to render real time business data with interesting visualizations, so people can feel the pulse of the business. For the last couple of months, I have been planning to write a detailed post about it. But after a few false starts, I am finally settling on smaller posts, telling a small part of the story each time.
So, have you ever worked on a web application that is primarily viewed through 55"+ 1080p TV screens?
Photo credits to  5mal5
We are showing real time business data, aggregated from multiple data sources as they are happening. The screens are gonna be mounted on the wall, like as you'd see in the airports. And it needs to be running 24x74

This introduces an interesting deployment challenge:
How would you reload the screen every time you re-deploy the app?

A regular web app is interactive. So, when we re-deploy the app, the users typically get the latest version as soon as they reload the page or navigate through the app. However, in an airport like setting, where information is displayed across many screens, and typically no-one is clicking it, the app needs to be aware of updates and reload itself to achieve the same. This is essential, for example, if there's an API change on the server side, the HTML/Javascript/CSS must be in sync to be able render it.

The app itself uses JSON API calls to render the live data. Each screen is somewhat like a single page app, using multiple AJAX calls to render different parts of the screen, showing different data. The API calls are all funneled through a single Javascript module. The module looks like the following (showing a simplified version for brevity): If you have noticed here, there's an extra check inside the success callback. To begin with, the page remembers the server token on reload. So, whenever there's a new token, it refreshes the page. Since all API calls are funneled through this module, this become a no-brainer to support new screens/API calls.

Our API's respond with a server token, which is guaranteed to:
  1. remain same for each server deployment, and
  2. change whenever there's a new deployment.
However, we still need to make sure the server token indeed ensures these two essential properties. With a little trick, this becomes trivial. For our app, we are using Capistrano to deploy our Ruby on Rails project. For those new to Capistrano, it uses a timestamped directory for each deploy, symlinking it to the current. So, it looks somewhat like the following: Every Ruby on Rails app also comes with a little method, Rails.root that returns the full path to the directory of the current deployment. So, in this example scenario, we get the following:

Rails.root #==> /app/realtime/releases/20120729083021

Since every deployment will be a new timestamp, this method ensures a unique token for each deployment. That's all we need for the api module to be aware of new deployments and auto refreshes. Here's an example controller/action (again, simplified for brevity): I liked the organic nature of this technique. It is harvesting on the available tools. Although the examples in this post show Ruby/Rails as an example, I am sure the same techniques can be applied to other technologies with the same simplicity.

Before I conclude, I would share one limitation of this technique here. Since the page reload happens on a shared api module, the reload needs to be generic, without requiring any special knowledge about the pages to reload. This pretty much means, a page needs to be able to reconstruct itself entirely from it's URL. Requiring any Javascript state beyond the URL, would probably require API specific handling to reload, killing the advantage of this technique. But the good news is, its always a good practice to rely solely on the URL to construct a page.

Thanks a ton if you've followed all the way. Stay tuned for the upcoming posts, where I will be telling the story of handling multiple API calls on a page, highlighting data changes and some other interesting bits about a real time dashboard.

Friday, September 16, 2011

How to Extend a Ruby Module?

Modules in Ruby are like classes with a few important differences. One of the differences is, a module cannot inherit from another module using the same syntax as class inheritance. However, its pretty easy to inherit a module's method into another module, by just using the include ModuleToInclude syntax. Here's an example if you are looking for one:

Friday, August 05, 2011

Ruby present? Method

Ruby has a nice little keyword called unless, that checks the opposite of if. So, you are probably used to a code like this:

return customer.first_name unless customer.nil?

If you haven't used present? before, you can in fact turn the above unless into a more familiar and easy to understand if statement:

return customer.first_name if customer.present?

So, in most cases when you are using unless with a negative condition, you can use present? and if instead. I find it way easier to read.

present? does the opposite of blank?. So, you will get the following:

nil.present? #=> false
[].present? #=> false
"hello".present? => true
["a"].present? #=> true
Hope it helps!

Friday, March 04, 2011

Whats Coming in MvcMailer NuGet 1.0?

Thanks to 365+ downloads of the MvcMailer NuGet before it hit version 1.0 and now its time to wrap up the NuGet package for an official first release. I got several encouraging feedback on this package and here's what you get from this first release:
  1. Use Scaffold Mailer to generate your mailers with views.
  2. Compose rich emails using your favorite ASP.NET MVC view engine.
  3. Use master pages and pass data using ViewData/ViewBag.
  4. Send multi-part emails for both text and html email readers.
  5. Put images inline so that they are visible even when email client is offline.
  6. Write unit test for your mailers and controllers that use the mailers.
  7. Send attachments.
  8. Send emails asynchronously.
To my knowledge, MvcMailer is gonna be the first full stack ActionMailer like Emailing library for ASP.NET MVC 3. If you are an ASP.Net MVC programmer who deeply care about high quality work and maximizing efficiency - you gotta try MvcMailer 1.0 for writing pretty email sending code.
The github wiki page has everything you will need to know about MvcMailer. Version 1.0 comes out on Monday. Stay tuned.

Friday, January 28, 2011

ActionMailer 3 - why do you call instance methods as class/self methods?

I didn't even notice this little trick! As long as I didn't have to call deliver_welcome_message (or deliver_*) methods that would magically call welcome_message, I was happy that now the magic is gone. Things are transparent!
Here's an example showing the change: Say you have the following mailer:
class Notifier < ActionMailer::Base
  def welcome_message(new_user)
    #a warm welcome message
  end
end
Now, prior to Rails 3, or ActionMailer 3, you would write the following to actually call this method to get the benefits of ActionMailer magics, such as finding the view based on method name and so on:
Notifier.deliver_welcome_message(new_user_instance)  
I am sure this deliver_* was a clever design decision to solve a hard problem, that is, finding the view name based on the method name. However, in ActionMailer 3, this is gone. Now the question is, if this trick is gone, how come it still finds the view name from the method name? Who sets the view name? To know the answer, first, let's take a look at how we call the welcome_message now.
Notifier.welcome_message(new_user_instance).send
Instead of

Notifier.new.welcome_message(new_user_instance).send

So, the magic deliver_ prefix is gone. But, did you see the new trick? Well, its a clever design again. The trick this time is, you call your instance method, welcome_message as if it was a class method. But there is no class method called welcome_message, so it instead goes to method_missing and thats how it sets up the view name from this call. Here's the code that does this little trick!
def method_missing(method, *args) #:nodoc:
    return super unless respond_to?(method)
    new(method, *args).message
  end
All it does is, instantiates the mailer with the method name!

However, this design decision has interesting side effects as well. Or may be not side effects, but rather core effects. For example, since you are calling your mailer methods as class methods, you cannot use a single mailer instance to send out multiple emails at the same time. In fact, every mailer has only one instance of message. So, it cannot store two messages at the same time. This is as if, you can have multiple methods in a class, but you cannot call more than one class or you will mess up the class's state!

Wonder why? Well, this is rooted in another key design choice: ActionMailer::Base is a subclass of AbstractController::Base. Now, if you look at controllers, you will notice that at any given point of time, a controller instance is only responsible for responding to a single action. This is logical for controllers. But how about mailers? I see a mismatch in my mental model and the actual implementation model. I don't see a reason why a mailer is a controller! For the sake of code reuse? But that could be done via delegation anyway.

I will end this post with one question:
Do you think mailer is a controller? hints: think about LSP.

Friday, December 10, 2010

Book Review: Jose Valim's Crafting Rails Applications

Have you already read this?

The following excerpt  by Jose Valim at the end of the book nicely summarizes it:
Finally, you understand Rails better. You can explore other areas of the source code, study other Action Controller and Active Models modules, check other generators implementations or read the source of Railties, Engines and Applications with detail! - Jose Valim
For the impatient readers, this is the best in-depth Ruby on Rails related book I have ever read and you should read this (only 172 pages). Buy the book here. But wait, you could get 40% discount and get the book for $13. I will tell you how, continue reading!
This book literally opens up the Ruby on Rails framework for the readers. So, now I am crystal clear about Metal, Rack, ActiveModel, Rendering, Templating, Migrations, Gems, Engines and so many core concepts. If you are like me, you have cloned the Ruby on Rails code and took a peek into the code to understand, patch some code or just to learn some hidden treasures of Ruby, but had tough time getting hold of the big picture. Well, this book will show you some highways and also some other useful alleys - you can find the rest by yourself!
This book embraces Test Driven Design, so all code examples, and hell yes there's a lot of them, are test driven. So, its unit test, functional test and integration test that drives the show. The topics cover customization of key Ruby on Rails components such as: models, controllers, views, mailers, generators and rack integrations. But the examples are really good as it shows:

  • Responding to pdf requests so that the server responds with on-the-fly PDF responses
  • Using Markdown templates for producing HTML and Text multipart emails from a single source template
  • Rendering views that are stored in a database to work as a simple CMS
  • Publishing and subscribing to Rails internal event such as SQL queries
  • Creating a simple rack application
  • Creating a Rails Engine
  • Creating custom responders so that you can DRY up your controllers that use exactly same lines for respond_to do |format|...
  • I18n translations using Redis key-value store and caching
  • Combining Sinatra with Rails in a single Rails app
To ease the process of trying out the DIY code, Jose Valim created an excellent gem called enginex. This gem gives you an incubator to try out the example code while building your own gem and using it from an embedded dummy application, writing tests and even browsing the app. The whole experience of trying out the code is awesome. Before this, I have never read a book that shipped with a gem just so that the readers could easily use the source code. Awesome idea and even better execution.
While explaining the inner workings of Ruby on Rails framework the book also discussed about a few useful gems:
  1. devise - authentication gem.
  2. enginex - produces incubator for gem development and makes it a breeze.
  3. capybara - drives integrations tests and also works with browsers through selenium etc.
  4. rdiscount - Discount is an implementation of John Gruber's Markdown markup language in C
  5. responders - DRY up your Ruby on Rails application with a number of handy responders.
  6. redis - an easy to use Key Value store.
  7. prawn - Ruby PDF library.
This book also shows a number of cool tricks. Its overall a fun read. I would say, the final version will be  more eye-soothing, but don't wait for that. Grab your ebook now and you will get the updates as they come!
I would like the book more if Jose Valim could reorganize some of the content. For an example, the text about Generators appear in different places. I think it would be easier to follow if it was in a separate chapter. The same applies for Engine.
I have another observation: the book is written for pro developers with substantial Ruby/Rails application. But I think the topics discussed here could also be equally useful to beginners. The later can be achieved by going a bit slow about some of the topics. Jose Valim, can you add little explanations at places for beginners?
The bottom line is, buy this book and read. To receive 40% discount, sign up at http://pragprog.com and refer to a friend and ask her to complete signup. You both get 40% discount. To claim, go to your account and you will find this as soon as your friend completes the signup.
Thank you!
--
This review is not sponsored and contains my opinion only.

Thursday, November 11, 2010

Ruby - some mysterious language features

Here I will share some of the interesting ruby features that you will notice when looking into mature ruby code by advanced level coders.

Wednesday, November 10, 2010

Upgrading to Ruby on Rails 3 - beware!

Ryan Bates had a series of posts (1, 2 and 3) on upgrading your Rails 2.3.x apps to Rails 3.x and sure they are useful. But if you are really doing that, beware of the following changes that you will need to do. It will take a lot of time for sure if you you have a moderate sized app.

Upgrading your models:

  1. Get rid of all validates_xxx_of with appropriate validates
  2. Get rid of all def validate ... end methods with custom validator
  3. Find out all occurrences of :conditions, :limit, :order and use new active record methods instead
  4. Replace all named_scope with scope
  5. Make sure your acts_as_xxxx plugins are all updated to use Ruby on Rails 3. I had troubles with Authlogic as it shows Based.named_scope is DEPRICATED. Still looking for a solution.
  6. Ruby 1.9.2 doesn't work with soap42 wsdl driver. Haven't found a solution yet as it keeps reporting an error regarding "XML processor module" missing.
Upgrading your controllers:
  1. Find out all occurrences of find method and replace with where.
  2. Find out all calls to Mailer that looks like deliver_xxx and make it xxx.deliver
Upgrading your views:
  1. All erb blocks must start with a has to be changed to  . Do the same for all such erb blocks with a do.
  2. All link_to_remote or remote_form_for or other remote form helpers need to be changed to their non-remote counterparts with a param :remote => true.
Upgrading your mailers:
  1. body method is gone, instead of the hashed params to this method, just define instance variables.
  2. All xxx.text.html.erb now becomes xxx.html.erb in the mailer views.
Upgrading the config files:
  1. The best way is to crate a new rails app and then copy the config folder into yours.
  2. Look at the initializers and clean up any required initializers.
  3. Make sure you have autoload_paths setup to include the lib folder. It is not included by default, so your code from the lib folder won't be accessible.
  4. Look at deprecation warning and you will see lots of config.action_controller.* need to changed to config.*
Plugins:
  1. All plugin/lib/rails/tasks/*.rake needs to be copied in to plugin/lib/tasks/*.rake
  2. Make sure your plugins don't use named_scope, if you find any, replace with scope.
  3. Whatever applies to your models should also be applied to your plugins that act on models.
Testing:
  1. Check you have updated shoulda, rspec or whatever lib you use.
  2. Update test codes according to your new lib.
Upgrading IDE to use RVM:
  1. Your IDE is not smart enough to use RVM. However use this to get TextMate ready.

Wednesday, September 29, 2010

Using nil.to_a or whatever.to_a in ruby

Ruby is a programming language for developer happiness and productivity for customers. Here is a quick happiness and productivity tip:

Monday, April 26, 2010

Using Authlogic and single access token for API access

Bynarylogic's authlogic has gained much popularity for its out of the box solution to ruby on rails authentication. Yesterday, I was working on giving API access to my ruby on rails application so that other apps can use my RESTful services. The authenticated API access usually involves the following steps:
  1. API_KEY or a token to identify/authenticate an API call.
  2. Authentication of an API caller using the API_KEY.
Authlogic comes with in-built support for this. The following steps will do it for you:

Wednesday, March 31, 2010

flash.now - did you know?

Well, I didn't know this until late. If you are like me, you have often wondered when you saw those unwanted flash messages appearing after a request, sometimes after ajax requests when you do a redirect, all on a sudden that flash shows up!
Well, as you have thought, the Ruby on Rails people have solved this problem way before now. The solution is to wisely use flash.now[] and flash[]. Here are a few tips:

Use flash.now[] when you are flashing:

  • on ajax requests
  • before a call to render :action => :my_action, as often found in failure cases of create and update actions
Use flash[] when you are flashing:

  • before a redirect_to, often found in the success cases of create and update actions
In general, use flash.now[] when you don't want to carry over the flash to the next http request and flash[] otherwise. The FlashHash class has more detail on this at the ruby on rails API page. Hope this helps you to get rid of those annoying and often embarrassing out-of-context flash messages!

Thursday, March 11, 2010

Ruby on Rails Security Review: An Experience Report

Image credits to Wink on Flickr (creative commons)

I was reviewing a Ruby on Rails source code to see the security implementations they have so far. They are about to launch their product for the first release and wanted to ensure they have the most obvious things checked. So, in a sense it was not supposed to be a hacking job for me, rather to check if the most well known security measures are in place. This is what I looked into so far:

  1. Password: Password was encrypted using a salt. However, the default logger would log the password as they didn't use the filter_paramerer_logging method.
  2. Cross-Site Scripting: I was able to easily inject a script by just entering <script>alert('Script')</script> when I signed up to the system and every time it would open an alert window whenever I navigated to a new page! So, I recommended them to use <%= h %>. However, Rails 3 does a good job of making this a default.
  3. Authorization: I found the weakest measure in the implementation of Authorization. For an example, there is a calendar in the web app where one can add/remove events. I found that any logged in user, not necessarily the event owner, could change/remove any calendar event. This was a shocker. Next, I found this same thing happening to the core models as well. The catch here is, they had a filter that checked if a user was logged in, but they didn't check if a user has rights to modify an instance of the object. For example, there is a project model, that can only be modified by the project owner. However, this per object ownership was not authorized and it was a huge potential security bug in my opinion.
  4. File uploads: The app was designed to upload the files to a folder underneath the public folder. Which means, if the rails server was down, apache would serve the files directly to the user bypassing whatever security measure was taken inside the app.
  5. PRG violation: This is a good idea to follow a post-redirect-get pattern when an object is modified through post/delete/put to ensure pressing the browser refresh button doesn't re-invoke the change. This wasn't done at some places which might end in multiple payments and such severe risks.
  6. Direct public release: I was a bit concerned that they wanted to go public release with their first ever release, even before having an alpha or at least in-house user. This is important because this application deals with money and credit cards. Trust is very important for such apps. So, I advised them to try this for some real works at home other than the "asdf asdf asdf...."(!) kind inputs. This will help them spotting some of the odd behaviors early and cause less embarrassment.
It was only a 4 hour assignment for me. Also, I was only limited to the source code and the test deployment that they have now. However, it seemed to me that, they might spend a few hours to fix the obvious errors and do some in-house real use before going to a public release.

Tuesday, March 09, 2010

Ruby on Rails or Rails on Ruby?

All on a sudden, this thing popped up in my mind. What we are calling Ruby on Rails, is this actually "Ruby" on "Rails" or the other way around? Is this upside down? Here's my mental picture of the RoR framework:
Image credits to Foo Fighter on Flickr(creative commons)

  1. Ruby is a self-sustained language. As a language this is completely ignorant of the Rails Framework. So, I think there is no dependency from Ruby to Rails.
  2. Rails is a framework built using Ruby as a language. So, there is a strict dependency from Rails to Ruby.
What do you think? Would you call it "Rails on Ruby" or "Ruby on Rails"? I see a point of agreement for the ones who want to call it RoR, no damage done :-)

Lets see how this "on" preposition works for other language/platform pairs:
  • Java on Struts vs Struts on Java
  • PHP on Cake vs Cake on PHP
  • C# on .Net vs .Net on C#
Confused? Well, then you can use RoR for now!

Friday, February 26, 2010

Rails Source Code Walkthrough #1: the ActiveModel Module

I was taking a look into the fresh ActiveModel module of Rails 3 as of github revision #100644. Here is what I learned:

  1. Learned about new feature called autoload. Rails Inside has a small yet useful autoload example here. It is a mechanism to lazy load your modules, so delaying the load unless the module methods are actually called. A call to autoload simply marks it as a potential include, but the actual include takes place only when you first use something on that module. I has a syntax like the following: autoload :Callbacks
  2. Using autoload, the ActiveModel module loads a number of other modules such as: AttributeMethods, Callbacks, Dirty, Observer, Observing etc.
  3. Also, it initializes the I18n Internationalization with the default en locale.
What's inside AttributeMethods?
This module defines class methods that lets you define attribute methods for the objects. I learned that you can have prefix, suffix and affix appended to your attributes that go to to a default method. For example, consider the following example right from the code:

# class Person
      #
      # include ActiveModel::AttributeMethods
      # attr_accessor :name
      # attribute_method_suffix '_short?'
      # define_attribute_methods [:name]
      #
      # private
      #
      # def attribute_short?(attr)
      # send(attr).length < 5
      # end
      # end
      #
      # person = Person.new
      # person.name = "Bob"
      # person.name # => "Bob"
      # person.name_short? # => true
Isn't this amazing?
What's inside callbacks?
Callbacks module is responsible for firing your before, after and around callbacks on ActiveModel models.
What's inside Conversion?
Conversion module only has 3 methods, to_model, to_key and to_param . These methods can be overriden to allow custom conversion of the ActiveModel objects.
What's inside Dirty?
The dirty module is all about dirty tracking methods of your ActiveModels. It has methods like changes, changed?, changed, reset_attr! etc. that you can use to track changes of your model objects. Thinks like history tracking or audition on changes can be done using this module methods.
What's inside Errors module?
This module has everything that deals with generating errors on ActiveModel validations. One ruby feature I learned from this module that I didn't know before. Its something like an indexer in C#. Here is an example from the source code:

# When passed a symbol or a name of a method, returns an array of errors for the method.
    #
    # p.errors[:name] #=> ["can not be nil"]
    # p.errors['name'] #=> ["can not be nil"]
    def [](attribute)
      if errors = get(attribute.to_sym)
        errors
      else
        set(attribute.to_sym, [])
      end
    end
    # Adds to the supplied attribute the supplied error message.
    #
    # p.errors[:name] = "must be set"
    # p.errors[:name] #=> ['must be set']
    def []=(attribute, error)
      self[attribute.to_sym] << error
    end
What's inside the Naming module?
Naming module is all about singular, plural, human and such names for your models! This methods are used to define the routes as well as in views. You can override such methods to provide a custom pluralized name for your model.
What's inside observing?
Rails Observers provide you a clean implementation of the Observer design pattern. It extends on top of the default observer module from Ruby. These observers are often use for implementing Aspect oriented programming as well as the code that are neither part of models or controllers, rather fall in between the two. Email notification is an useful example from Rails Guides.
What's inside the Railtie module?
Well, not much! But it glues up ActiveModel with Rails! Just two lines of code as folllows:

require "active_model"
require "rails"
What's up with Serialization?
It has only one method that generates a hash based on the serializable attributes with :only and :except filter!
What's inside Serializers?
It has two serializers, one for json and another for xml. This two works great out of the box. However, if you need to tweak it, it should be very simply done by subclassing this classes.
What's inside translation?
It translates your model attribute names to match your locale using I18n. The default skim looks for the following naming in your local yml file when called through the method human_attribute_name
activemodel.attributes.underscore_model_name.attribute_name
Whats inside Validations?
This is a freshly renovated module for Rails 3, as it merged the validates_presence like methods into a single method validate that lets you keep all your validations for a model with a single call. Also you can easily reuse custom validators through out your models.
But this forked a few more modules, one per kind of validation. All these validations and your potential custom validators will probably be descendent of the Validator class that has the following method:

# Override this method in subclasses with validation logic, adding errors
    # to the records +errors+ array where necessary.
    def validate(record)
      raise NotImplementedError
    end
Some in-built implementation of this validator are acceptance, confirmation, exclusion etc. I learned something new here, the NotImplementedError exception.
So, what's the big learning here?
  1. I will use Modules to modularize my ruby code. This perfectly makes sense and also this is how one can come up with plugins out of their code base. Having the small bits in a module also facilitates reusability inside a project.
  2. The source of ActiveModel is very simple and completely ignorant of its underlying database. This is the big change of liberating Rails from ActiveRecord, which I think is not a matter for most rails developer anyway! But its a good lesson learned.
  3. Once I see some time, I would like to jump in to the development of Rails, at least make some initial contribution.
Stay tuned for more posts on Rails 3 source code.

Tuesday, February 23, 2010

Ruby on Rails Interview Questions: Advanced

In my previous post, I listed a few general interview questions for Ruby on Rails jobs. This one is intended to be more of an advanced level, not for the rookies :-)

  1. What is Rack?
  2. Sketch out a deployment architecture of a Ruby on Rails application utilizing multiple servers.
  3. How can you secure a rails application to counter for Session Fixation?
  4. Where can I get the core rails framework source code?
  5. How can you reuse the models from one rails project into another?
  6. Explain one plugin that you extracted out of your source code.
  7. What is the difference between pre-initializers and initializers?
  8. How can you easily switch your logger to use Log4r?
  9. How would you design the logging standard for your rails application?
  10. How can you implement asynchronous messaging in Rails?
  11. What will you do to look for a possible memory leak in Rails application?
  12. How can you run a profiler?
  13. What is lambda?
  14. What is Proc? When did you use this?
  15. How can you use before and after callbacks of your rails methods to halt a database insert/update/delete?
  16. How can you reuse your before and after callback methods across multiple models?
  17. Define an architecture to store files uploaded to an application so that they are only accessible to valid users.
  18. How would you change your asset storage to use a static server?
  19. Explain one situation when you used rails caching.
  20. What kinds of caching comes in-built with Rails?
  21. Can you explain the use of 'dynamic' features of Ruby on the core Rails framework?
  22. How can you call a SOAP web service from a rails application?
  23. Your application needs to send a lot of email notifications. How would you design the notification so that the end user doesn't get stuck for email sending delays?
  24. What is a mongrel cluster?
  25. Can you explain if the clusters share a same memory? Can one cluster handle a request from a client that was handled by another?
  26. How would you internationalize your application interface?
  27. How can you create a rails generator?
  28. Have you ever used a polymorphic association?
  29. How can you define a plugin that adds a new class method to ActiveRecord::Base?
  30. What are the three most significant changes in Rails 3 in your eyes?
  31. How can you implement complex reporting using ruby on rails?
I am sure this list will go on and on. But I have found most people asking questions about scalability, deployment issues, security and such architectural level questions to extract out the in-depth understanding of such core concepts. Where to learn more on such advanced stuffs? Ruby on Rails Guides and Stack Overflow are my favorite places. However, its good to keep an eye on the edge rails to see what's happening today! 

Monday, February 22, 2010

Ruby on Rails Interview Questions

Ruby Specific Questions
The best place for learning ruby is to get started with the programming-ruby. It fairly covers the important bits in a very readable language. Here are a few quick questions on ruby:
  1. What is rubygems?
  2. What is a Symbol?
  3. What is the difference between a Symbol and String?
  4. What is the purpose of yield?
  5. How do you define class variables?
  6. How do you define instance variables?
  7. How do you define global variables?
  8. How can you dynamically define a method body?
  9. What is a Range?
  10. How can you implement method overloading?
  11. What is the difference between '&&' and 'and' operators?
  12. What is the convention for using '!' at the end of a method name?
  13. What is a module?
  14. What is mixin?
  15. How will you implement a singleton pattern?
  16. How will you implement a observer pattern?
  17. How can you define a constant?
  18. How can you define a custom Exception?
  19. How can you fire a method when a module is included inside a class?
  20. What is the default access modifier (public/protected/private) for a method?
  21. How can you call the base class method from inside of its overriden method?

Rails Specific Questions
A thorough reading of the articles at Ruby on Rails Guides can be very useful for starters as well as a refresher for veterans. The following bunch of questions are specific to rails, in no particular order. The Pragmatic Bookshelf has a fantastic book for beginners called Agile Web Development Using Ruby on Rails.
  1. Define the Rails MVC implementation using an example.
  2. What is a named scope? (or Scope in Rails 3).
  3. Can you give an example of a class that should be inside the lib folder?
  4. Where should you put code that is supposed to run when your application launches?
  5. What deployment tool do you use?
  6. How can you migrate your database schema one level down?
  7. What is an observer?
  8. What is a sweeper?
  9. How can you implement caching in Rails?
  10. What is a filter? When it is called?
  11. How can you divide your controllers into separate modules?
  12. What is RESTful routing?
  13. How can you list all routes for an application?
  14. How can you send a multi-part email?
  15. Is it possible to embed partial views inside layouts? How?
  16. What is the purpose of RJS?
  17. How can you create a REST API for your application?
  18. How can you define a new environment called 'staging'?
  19. What is Rake?
  20. What is Capistrano?
  21. What is a polymorophic association?
  22. How can you implement a polymorphic association?
  23. What is a has and belongs to many association?
  24. What is the difference between has_one and belongs_to?
  25. How can you implement single table inheritance?
  26. What is eager loading?
  27. How can you eager load associated objects?
  28. How can you add a custom validation on your model?
  29. How can you implement a custom theme for your forms?
  30. Why is fields_for used for?
  31. What is the purpose of a helper method?
  32. What is flash?
  33. How can you install the missing gems that are required by your application in the simplest way?
  34. How can you implement internationalization?
  35. How can you show search user friendly urls instead of using only numeric ids?
  36. How can you configure your application for different environments?
  37. How can you instruct rails logger to ignore passwords and such fields while logging?

Test Frameworks
Ruby on Rails has a number of built-in and a few other third-party test frameworks. Here are a few sample questions on such frameworks:
  1. Are you familiar with unit testing?
  2. How does functional testing differ from unit testing?
  3. Have you ever used a mocking framework?
  4. Are you familiar with BDD using RSpec or Cucumber?
  5. What is an alternative to using test fixtures?
  6. How can you reuse part of a text fixture?
  7. How do you specify associations in the test fixture yml files?

Plugins
Plugins are the principal mechanism to reuse code. The open-source community is at full-bloom when it comes about plugins. The Rails Plugins site has a really good list of such plugins from the community.
  1. What plugin would you recommend for user authentication and authorization?
  2. What plugin do you use for full-text search?
  3. How can you implement a state machine?
  4. What is the difference between a plugin and a gem?
  5. How can you create a plugin?
  6. Can you please name a few useful plugins?
  7. How can you implement a search feature that searches for multiple models?
  8. How can you upload a flie to a server?

Architecture Related Questions
This questions can be from different angles like: quality, security, scalability, manageability, interoperability, reusability and all the other ilities you name! Here are a few example questions:
  1. Is Rails scalable?
  2. What are the key deployment challenges?
  3. How can you safeguard a rails application from SQL injection attack?
  4. How can you secure a rails application?
  5. How can rails engage with a SOA platform?

Community Related Questions
I see a fairly large community on Github, Stack Overflow, RailsCasts, The Riding Rails Blog and many more. Some interviewers may want to see if you are connected to the community. The following questions may help you prepare :-)
  1. Can you tell me a few good community resources for Rails?
  2. Where would you reach out to get the community to answer your questions?
  3. What's new in Rails 3.0?
  4. Which famous applications are built using ruby on rails?
I plan to polish this document on a later revision. But in the meanwhile, if you feel like contributing, you can start commenting with the answers, more questions or suggestions. I believe this will not only help people getting ready for their next Rails job, but also for everyone to see what knowledge we are missing...
Disclaimer: This is not a shortcut, rather its kind of a check list that may help you with an interview.

Wednesday, January 20, 2010

Experience notes from a RoR code review job

Recently I had the opportunity to review a ruby on rails code. The project aims to create an online market place for experts, with a similar model to some other freelancing/outsourcing sites. Here is how and what I reviewed:
I had a read-only access to the code and no download was allowed locally. So, I didn't get to run the code, tests or any tool to auto-generate some reports on the code. Also, it was supposed to be a high level review and I was supposed to take 5 hours to take a look into the code and write a report on the various aspects of it. In the end, it took me 6 hours and I came up with a 14 page report. I liked this job for a few reasons:

  1. When I was working at www.ScrumPad.com project, we got our code reviewed by Gregg Pollack of RailsEnvy. During those days we had little experience on RoR before we started the project. So, we ended up with something that was working well, but wasn't the best one in terms of confidence and reliability. I remember the review was very well-thought and presented by Gregg and that to a great extent shaped the later works on the project.
  2. This was my first official assignment as a reviewer.
  3. I was excited to see how other people were approaching their RoR projects.
 Now coming to my review approach, here you go:

  1. After some googling about reviewing RoR applications, I didn't find any comprehensive suggestion and decided to go my own way.
  2. To get started, I took a look into the config/routes.rb file. I had the impression that, routes.rb would help me understand the resources and their relationships. But soon I discovered one potential issue as there were almost no nesting of resources and some resources had tens of actions apart from the standard RESTful methods.
  3. Next, I picked the resource with most number of methods and found that, it was actually taking the responsibility of 5 different resources. Although these resources were somewhat related, it made little sense to me to have such FAT controllers.
  4. I was also looking for logging, exception handling, ruby coding style, naming and came up with some suggestions to improve on these aspects.
  5. I also suggested them to modularize their controllers. They already had an admin module, but they could introduce more to clean up things.
  6. After controllers, I went to the models. By the time I found a few natural inheritance relations among the models. But the relations were not found in the models that ended up with a number of code duplications and similar looking branches at several places. So, I suggested them to install the relations using single table inheritance and cleanup the stuffs.
  7. Apart from the relations, I also found a number of self or class methods floating here and there. While ActiveRecord models themselves offer a number of such methods, its not always wise to create one without thinking. In the code I found self methods resulted in method duplication and wrong method placement at several places.
  8. Next coming to views, I found they did a good job with the helpers and partials. Views were better organized. But also, I found a lot, I mean a lot, of partials. Such an explosion of partials often makes it hard to find the right ones, especially for new comers.
  9. Going to test code, I found they had a test suite with unit, functional and integration tests. But the amount of test was a concern for me. I believe test codes are there to help good design practices and managing changes over time. I suggested them to target 80% test coverage at a minimum.
  10. Coming about deployment, I found they were using manual deployment techniques. I suggested them to use capistrano for deployment.
  11. Overall I found a lot of reinventing the wheel scenario as they could get rid of lots of code by just using commonly known and free plugins. I suggested some plugins in this regard.
  12. I suggested them to use named_scopes to get rid of some self methods here and there.
After the review, I felt such patterns in RoR code is expected to surface in most new to RoR teams. Although experienced and smart people often read articles and consult experts as an on going basis to get things right at the first place. I suggest every team, if they haven't already gone through, to take some time and study the resources at http://guides.rubyonrails.org and http://wiki.rubyonrails.org/
Also, its a good idea to know the Ruby language fluently to make use of the power of the language. A good learning resource comes with ruby installation named Programming Ruby, also available in the internet at http://ruby-doc.org
As a continuous learning tool, I also suggest keeping an eye on http://railscasts.com and http://stackoverflow.com/questions/tagged/ruby-on-rails

Sunday, December 27, 2009

Added Crummy to generate breadcrumbs for CampZero.com

According to google's SEO guideline, its a good idea to provide breadcrumbs to your web contents. This is good in two ways: a) It helps people to find path to move up the navigation stack and b) it helps the google and other search engines to get a feel about your web content's hierarchical organization.
To add this breadcrumbs support, in my application www.campzero.com, a going to be online service marketplace for Bangladesh, I simply used the Crummy plugin. You can take a look at the Crummy plugin at github. It took me less than 10 minutes to find, learn and use this plugin! You can see the plugin in action at the campzero site.
I recommend this plugin for your Ruby on Rails breadcrumbs needs!

acts_as_permalinkable: SEO friendly rails URLs using my first RoR plugin

As a byproduct of my work on www.campzero.com, I released my first ruby on rails plugin called acts_as_permalinkable on github athttp://github.com/smsohan/acts_as_permalinkable
A comprehensive documentation is given at the github page. If you ever need to use search engine friendly urls or permalink like this blog, you may consider using the acts_as_permalinkable plugin. It takes less than 3 minutes to add the permalink feature to your rails model!
Get started by the following and you are free to contribute!
script/plugin install git://github.com/smsohan/acts_as_permalinkable.git