Category: Ruby on Rails ++

7 Great Websites Built Using Ruby on Rails

When it comes to web development, Ruby on Rails is our bread-and-butter. Our team is skilled using RoR, and we’re proud of the amazing things we can do with it. Of course, RoR is also an open source project, so a lot of people have been able to create some pretty great websites using it. Below, we’ve listed seven of our favorites that you might recognize. Many of these immensely popular sites are so large and complex, it’s no wonder they relied on Ruby on Rails developers.

1. Hulu


Hulu has relatively recently become the go-to place to catch up on TV shows online. They also host movies and exclusive Internet videos. If you have access to Internet, you no longer have to worry about missing the latest episode of your favorite show. RoR helps make Hulu’s large library attractive and easy to navigate on a variety of platforms.

2. Funny or Die


Funny or Die is comedian Will Ferrell’s brainchild. It hosts a deep database of videos featuring Ferrell and his funny friends, as well as other hilarious videos and pictures from around the web. Since the site is built on RoR, it boasts a number of slick features, like a community-based voting system for determining if a video is “funny,” or if it should “die.”

3. Yellow Pages


Remember “phonebooks?” Yeah, we don’t either. This website is the online incarnation of the giant yellow phonebook that used to (and occasionally still does) show up on doorsteps around town. This version doesn’t ever need recycling, and good RoR development has made it a joy to use.

4. Bleacher Report


Bleacher Report is a sports-focused website that relies heavily on user-created content. Because of the vast network of contributors (there are roughly 1000 original content postings a day), Bleacher Report needed to be a user-friendly system. It also integrates social media directly into the site.

5. Basecamp


Basecamp started it all. The Ruby on Rails framework was extracted from Basecamp, a web-based project management tool. Between providing the world with RoR and helping workers track progress on projects easily, Basecamp has created many unique experiences for a wide array of users.

6. Groupon


When Groupon first hit the scene back in 2008, it made huge waves in its test market of Chicago. Four years later, the company has expanded into cities around the world and now offers consumers a way to get great deals right in their own neighborhood. With RoR, their site has been designed to be simple and user-friendly, ensuring that each visitor gets exactly what they want.

7. Manage My Life


Manage My Life is a destination for life management that helps do-it-yourselfers cross items off their to-do lists, manage projects, find expert answers to their questions, and even download product manuals for tools around the house. Managed by Sears, the site was built on RoR to give Sears customers an easy way to put their purchases to work.

These sites are just a handful of examples of great things that have been done with Ruby on Rails development. What have we missed? Share some of your favorite RoR sites in the comments below!

Ruby on Rails for Startups!

Choosing a technology platform is a key decision for all startups and an adept entrepreneur never misses to consider both strategic and technology perspective while selecting one. What matters most for an intelligent startup?…time to market? quality? money? When enticed to take on the latest “silver bullet” technology, startups need to cautiously weigh the associated gains and trade-offs. Synonymous to rapid web development, ruby on rails is twice as fast to develop as Java and twice as maintainable as PHP. Gartner’s prediction of a fourfold increase of Ruby developers to four million by 2013 further substantiates this fact.

What makes Ruby On Rails a startup technology??

Less is More

Less time constructing, more time creating. Less code, more fun. That’s what Ruby is all about. The combination of the language (Ruby) and the framework (Rails) means you can do more with less code. Less code, with better-structure, implies enhancements are relatively painless, giving startups the flexibility to iterate and experiment more readily. Furthermore, readily available open-source gems and plugins for Ruby on Rails can help build anything from throwaway prototypes and internal utilities to meticulously crafted full-blown web apps.

It’s zen, it’s fun and it’s cool

Rails is cooler. Its true! Haven’t you heard about FullCodePress, a competition to build a website in 24 hours, won by a Kiwi team using Ruby on Rails. Ruby is not only very succinct, making it one of the most expressive language, but with well defined “full-stack” framework that covers both front-end and back-end design, making it a nifty tool for “jack-of-all-trades” developer.

Risk & Reward

No risk. No gain. And, what could be riskier than building a business on a relatively new technology platform? However, there’s a catch here. Since the project is open source one can easily fix it himself if things go downhill. Consequently, though all startups involve risk, its much wise to take risk on things one can control (like the technology platform) than taking on “market risk” and things that one can’t control. Additionally, quick, neat and easy development allows ROR professionals to help startups with quick turnarounds for less money, thereby providing provision to the startups to play with a not-so-great or non-existent market opportunity. If the business idea doesn’t sell, it only took a couple of months for the startup to build it anyways, giving newbies the confidence to just start over and get it right the next time.

Galvanize VC Interests

Venture Capitalists are always on the lookout for startups that believe in pushing the envelope on new technology and leverage the synergies that come with the seamlessly integrated and psychotically intuitive and elegant coding style that is inherent in Ruby On Rails. This also aligns with their focus on funding startups that are curve-jumping, paradigm shifting and market exploiting. All things being equal, you’re more likely to raise funding if you’re on RoR than if you’re using one of those other web platform/frameworks.

Guaranteed Good Design

Fact that the entire MVC pattern is “baked in” to RoR, it keeps newbies and intermediate programmers from shooting themselves in the foot. While one can do MVC with Java and C# as well but these languages give far too many options, creating dependency on the development team. RoR makes all the standard default choices for the programmer, allowing him to tap into the global development pool and be on top of the latest best coding practices.

Programmer Potency

Ruby, a language explicitly designed to increase programmer productivity, is adapted as an “escape” from conventional web development technologies such as .NET and Java, which aren’t as well suited for rapid web development. RoR can successfully turn a naive Java developer with 6 months experience into a valuable member of ROR development team. Subsequent increased productivity of RoR developer leads to the benefit of accelerated experience.

QA with Agile teams

Agile methodologies foster accommodating frequent changes. This means the test case documentation will soon become obsolete. Some projects have very short sprints or iterations. The manual tester might not have all the time in the world to go sequential by first preparing the documentation and then begin to test. Some of the projects are even more nasty where the requirements would change in the same sprint itself.

Agile testing is characterized by quick iterative life cycles which squeezes tester’s ability to develop and maintain test cases, leaving very less time for documentation. Consequently, in this high paced agile environment, one is always on the lookout for tools that facilitate easy and quick documentation and test case preparation. ‘GOOGLE DOC’ is one of the pragmatic options readily available FOR FREE to use.

Yeah!…everyone knows about google docs but do we really use it?

How does Google Doc help in Agile Testing?

1. Test cases are easy to prepare, save and share with the clients and within team members.

2. All team members in the project including client, developers, testers, designers etc. get updated with the current status of the project.

3. Each member is aware of his/her tasks and get updated with the bugs and changes they have to work upon.

4. Good to make runtime changes particularly with frequent requirement changes.

5. Team collaboration helps everyone work together towards the common goal.

6. Maintains Versions of changes to the documentations as well.

7. Most importantly, keeps transparency towards the client.

I generally use the below template while testing multiple projects in agile and it’s been a great asset until now!

If you have the liberty you can also employ tools like Pivotal Tracker, Redmine, etc. These tools are easy to maintain and offers a user friendly UI to put across requirements and feedback.

Now that I spoke about the testing tools, let’s have a look at few small but important things which a tester can keep in mind while testing the web app:

About UI:

1. As the requirement changes, the UI does too and at times quick and dirty addition of buttons and links occur. As a tester, you must ensure that the positioning of buttons is consistent with the overall design.

2. Undo links such as cancel, back, previous often gets less attention from the designers as it does not fall in the happy path of the functionality being worked upon. As a tester, you must ensure they get enough attention and user friendly space in the design.

3. At times developers take the liberty to color links in an inconsistent manner than the designer style guide. This happens when they suddenly add a link that is not part of the PSD. As a tester, it is important to ensure things that are not part of the PSD but are yet put in, fits with design consistency.

4. Another place where design looses consistency is usage of capitalization. For example: some buttons remains capitalized while some do not. Keeping a check on this is important for better user experience.

5. Error messages should get listed as per the sequence of fields on form.

6. From cross-browser compatibility perspective, its often better to first get the application stabilize on Firefox and chrome and only then moving to getting our friend IE happy.

7. It is very easy to miss out on a missing icon. Keeping a good eye on that is equally important to justify the hard work that the designer might have put in to get the fine details look good.

8. Communicate with images than words. Use of screenshots to highlight bugs/issues. Use software like ‘Screen Capture’, ‘Fire shot’ so that one (client and developers) can easily understand bugs.

Functionality checklist:

1. No link is left behind. It is often the case that the developer misses connecting the link. Checking each link is functional is our responsibility as a test person. For identification of links you can use ‘Link Checker’ for each page.

2. Make it easier for the developer by using the same tools they do. Install firebug and report any errors that it spits out as it is to the developer. It makes their lives easier.

3. Manual testing is hard and ensuring everything is working as required at times gets tiring. Take a quick 2 minutes break after every feature or do something that you like. That keeps the mind active.

4. A good QA person would be able to spot dependencies. When something new is added or a bug fix just made it, what else could break? Thinking about this constantly ensures new code does not make the old one unhappy.

Live Push today??

In agile testing live push is an important and regularly performed activity. Consequently, it’s difficult for tester to test all functionalities in detail and ensure a stable system before deployment. While going live following things can help:

1. Test all the high priority bug fixes/changes first

2. If any input field gets added that may affect the database then check out for data inconsistency in the associated fields.

3. Report the broken pieces as they occur to you immediately so while you are still testing, the developer can start to fix the broken piece.

4. Be sure to meet the scope for each sprint for each go live.

5. Ensure the environment is stable to execute final round of testing before go live.

6. Regression testing is must. Ensure that a change, or bug fix, does not introduce new faults/bugs.

7. Ensure once again that the application is stable on all the browsers (as per requirement).

8. Update the status immediately as resolved so that everyone in the team can get a feel of the overall status.

9. In short of time if some bugs/issues not resolved before release, inform client with the issues and their severity.

Process -> Process in CarrierWave

Well, this one is for all those who ever used CarrierWave for uploading their files(no matter which files). Now how many of us had actually extended Carrierwave to process a file (i.e writing you own processing for the file e.g In term of image reducing or increasing the quality of image)I happen to stumble upon this as all I want was to process a CSV file which is suppose to be stored in Amazon S3(on upload) using CarrierWave .

Now the aim was to extract all the information from the CSV (sound simple right ). Yes, it is but I resist the thought of putting the file in Amazon S3 server(first) and then downloading the file and to my server and then extract the data from the CSV file and dump it into the database. I want it to be more real time(since the file is small size file) I want the user to know that the data in CSV is proper or not and can or cannot data in the CSV can be dumped into database citing validations.

So I realized back when I used to consider PaperClip as my first options, paperclip used to provide me options for processing the file here the link if you want to do it for paperclip Good Luck.

Yes I knew now I have to achieve something of this sort , but howWell, looking at the uploader file generated by CarrierWave I found out that there is process method, ok now what how do you apply it.
Inspecting the CarrierWave source code ( for default resize process ) I found out that all you need is to define a method wrapped inside a module .

Now it got it.

So to define a custom processing all you need is to define method wrapped in module and include that module in CarrierWave and pass your process method as an argument to CarrierWave process method define in uploader file
Here how I achieve this.
Inside CarrierWave Uploader

class AssetUploader < CarrierWave::Uploader::Base
   include CarrierWave::CSVProcessor
   process :process_csv
end

That it that all you need to do to define your own file processing.
Just go ahead an define your process_csv method inside module define in file inside config/initializers Voila mission accomplished.
Here how I did it (my file config/initializers/csv_processor.rb)

module CarrierWave
  module CSVProcessor
    def process_csv
      ....
      ....
      ....
    end
  end
end

Go hack now with CarrierWave.

By the way if you want to explore the thought of providing custom error message for CarrierWave here a link that you might want to look at

Hope that it help you in someway or other

Ruby on Rails Observer Implementation Part 2

In my previous article i had gone through how ruby observer works if you haven’t read it check it out.

In this article I will go through how the rails observer works and how callback are notifying the observer.

I’ll be jumping through 2 files so keep it open, it will help you to understand the workflow of how rails’ observers work.

  1. Active Model Observing
  2. Active Record Observer

Consider having a contact and account model and adding observers to both models.

class AccountObserver < ActiveRecord::Observer
  observe :account,:contact
  def after_create(record)
   # do some stuff
   # ......
   # do some stuff
  end
end
# Add to config/application.rb
config.active_record.observers = :account_observer
  1. When rails boots ,the observer is initialized by calling AR::Base.instantiate_observers in AR Railties.
  2. It calls the instantiate_observers of active model’s observing module.
    • Which creates single instance of observer class by using the singleton module .
      eg. AccountObserver.instance
  3. After creation the instance is initialized. It does the following things.
    • Finds all observable classes (:account,:contact)
    • Adds the observer to them
    • eg. Account.add_observer(AccountObserver.instance)
  4. So the first step is to get all Observable classes which we will get by calling observed_classes.
    observed_classes is overridden by AR::Observer

    • It gets all observable classes by calling super. It will get all classes via the observe method which is explicitly defined or by the class name of observer.
    • If there are any subclasses (descendants) classes it will also observed too.
    • eg. Account,Contact
  5. Now after getting all classes the observer is added this can be done by calling add_observer!(klass)
    add_observer!(klass) is again overriden by AR::Observer

    • It adds observer to all observable class by calling super
    • And then it calls define_callbacks method which is present in AR::Observer
  6. define_callbacks method is responsible for adding notification support for observable class
    • It traverses all AR::Callbacks and if observer method matches AR::Callback method then
      it creates a dynamic notification method which would look like _notify_#{observer_name}_for_#{callback}
    • This method is added to observable class(Account) and its called on the callback
    • eg. after_create :_notify_account_observer_for_after_create
  7. When the callback is invoked (in our case after_create) it will call its respective notification method
    • Above notification method has following definition.
      observer.update(callback,self,&block)
    • Update method again check callback method is present in Observer instance if yes then it call callback method of Observer class
    • eg.
            
         AccountObserver.instance.update(:after_create,record,&block)

      it check and call after_create of AccountObserver class.

I hope it is helpful to understand how rails observer is implemented.

Comments and feedbacks are welcome.

Auto Login from Iphone Home Screen Shortcut using LocalStorage and Rack

If you ever worked on Mobile Application and if you have been ever asked to design a web auto login for iOS Home Screen Desktop every
time a user click the Home Screen Shortcut then you might want settle down and read this post bcoz this can help you.

The first that I came across when implementing the home screen shortcut how to manage the cookie and how to store in browser
(even when browser is closed)

Thank full to HTML5 as it provide a localStorage I quickly got the insight how where to store the cookie

For any one how aren’t aware of HTML5 localStorage. HTML5 localStorage provide API for storing data locally on browser which can be
access any time by your application in near future.

Now with clear insight of where to store the cookie the next task is how to access it and wrap it in request.

That when Rack Hit me

The idea is to mount a rack application on top rails middleware and then play around with Rails request/response cycle. Let me Hook up the code to then explain you everything bit by bit

CODE = %{} COOKIE = %{} def initialize(app) @app = app end def call(env) if iphone_web_app?(env) if new_session?(env) [200,{'Content-Length' => code(true).length.to_s, 'Content-Type' => 'text/html'}, code(true)] else status, headers, body = @app.call(env) request = Rack::Request.new(env) response = Rack::Response.new([], status, headers) cookie = String.new request.cookies.each_pair do |key,value| cookie += "#{key}=#{value};" end body.each do |part| part.gsub!(/</head>/, "#{set_cookie(cookie)}") response.write(part) end response.finish end else @app.call(env) end end protected def code(resend=false) regex = "_session_id" if Rails.configuration.session_store.name == "ActionDispatch::Session::CookieStore" regex = Rails.configuration.session_options[:key] end CODE.gsub('{{RESEND}}', resend.to_s).gsub('{{REGEX}}',regex.to_s) end def set_cookie(cookie) COOKIE.gsub('{{COOKIE}}',cookie.to_s) end def new_session?(env) request = Rack::Request.new(env) if request.cookies['_cookieset_'].nil? true else false end end def iphone_web_app?(env) if env['HTTP_USER_AGENT'] env['HTTP_USER_AGENT'] =~ /WebKit.*Mobile/ && !(env['HTTP_USER_AGENT'] =~ /Safari/) end end end

Now the idea is to trap the request def new_session? which has no cookie associated with it return the code javascript in response body and extract the cookie from localStorage localStorage.getItem(‘__cookie__’);
associate it with document using document.cookie syntax and re-request the page using window.location.reload()

Voila there you have it next time you open your Home screen shortcut you would not be thrown to login screen citing no active session available.

Hooking all of this in one gem called rack_iphone

Note : There are other way you can achieve the same using parameterized URL (where a URL will be identify with the parameter in it) something like GOOGLE does I Guess.

Providing few links which will further help you so that you don’t stumble upon any roadblocks when building the same
LocalStorage Issue

ACTIVE RECORD ASSOCIATIONS TIPS AND TRICKS

After using Active Record in Rails all this while I have finally realized that when it comes
to associations some of the techniques being used were absolutely unwieldy and literally choked life out of my applications.
Not that these are anything new, but having learnt first hand I am compelled to discuss some of the do’s and don’ts when
dealing with the relationships in Active Record.

Proper usage of Collect & Select:

As we all know, collect & select are so widely used to iterate over collections and return,
only required collections through one liners. These one liners look beautiful but, we need to use these quite carefully. Actually
we need to use collect only for collecting attributes of one particular Table/Model

COLLECT:

We can use COLLECT only for COLLECTING ATTRIBUTES of existing Collection
Ex: Theme is a model with name as an attribute. To collect all the theme’s names, we can use collect as below.

  
Theme.all.collect{|theme|theme.name}

Its not preferable to use collect for collecting ASSOCIATIONS RECORDS. To get associations records, we can use :joins, with
select attribute or :include.

SELECT:

We can use SELECT to select records by checking conditions on existing collection
Ex: Theme is a model with name as an attribute. To select themes which have name,

  
Theme.all.select{|theme|theme.name.present?}

Its not preferable to use select to verify conditions related to associations. To get
associations records, we can use :joins with select attribute or :include. Using collect or select on associations will fire
lots and lots of unnecessary database queries, which will lead to slowing down of our application. Here we can see the difference.
For example, lets take a complex association hierarchy to see the difference in number of queries being fired, in different cases.


active_records_tips01

 

# To collect all questions related to a theme

  
Theme.first.topics.collect{|topic|topic.questions}.flatten

OR
# To get all topics which have at least 1 question

  
Theme.first.topics.select{|topic|topic.questions.present?}

Both will fire the queries, listed below.


active_records_tips02

Here, by calling questions association on topics through collect or select, it fired,

  • 1 query for getting the required theme
  • 1 query for theme.topics
  • 5 queries fried for topics.collect{|topic|topic.questions} or topics.select{|topic|topic.questions.present?} (here, number of queries firing = number of topics in given theme.)

collect / select part fired 5 queries, because, there are 5 topics in selected theme. If there are 100 topics in the selected theme, it is going to fire 100 queries, which is not at all necessary.

1) For collecting all the questions of a theme, we can use :joins as shown here.

  
Question.find(:all,
  :joins => "INNER JOIN questions_topics on 
  questions.id = questions_topics.question_id",
  :conditions => "questions_topics.topic_id in 
  (#{Theme.first.topics.collect(&:id).join(',')})",
  :order => "questions.title ASC")

Here, it is getting all the questions related to all the topics of a theme with just 1 query

  • 1 query for getting the required theme
  • 1 query for theme.topics
  • 1 query for getting questions related to all the topics of given theme. (irrespective of the number of topics in given theme.

2) For getting all the topics of a theme, which have at least 1 question, we can do Eager Loading and then, use select as below.

  
topics = Topic.find(:all, :include => [:questions], 
:conditions => "theme_id = 1")
  topics.select{|topic|topic.questions.present?

Here, it is getting all the questions related to all the topics of a theme with just 1 query

  • 1 query for getting the required theme
  • 1 query for theme.topics
  • 1 query for getting questions related to all the topics of given theme. (irrespective of the number of topics in given theme.

About :include and :joins

  • Joins joins tables together in sql
  • Include eager loads associations to avoid the n+1 problem (where one query is executed to retrieve the record and then one per association which is loaded).

Similarity:

  • Both Include and Joins are used to get data from 2 or more tables at a time.
  • Both are interchangeable most of the times with some syntactical changes.
  • Both work at any given situation, but best usage depends upon the requirement.

Differences:

Joins:

  • We can select the fields to fetch from different tables
  • It will just joins the tables together in sql
  • Its light weight and fast, as we can select the fields and only joins tables

Include:

  • We can not select the fields to fetch. Even we try to select, it will just neglect. It will fetch all the fields from all the matching records from included tables
  • It will eager load the associations into memory
  • Its heavy and slow, as it eager loads all the associations into memory

Usage:

Without using joins or includes, if we try to access records and their assocations, there will be soo many queries as showed below.

  
Theme.first.topics.collect{|topic|topic.questions}.flatten.uniq
.collect{|question|question.answers}.flatten.uniq

It will fire below queries.
active_records_tips03

if 1 theme has 5 topics, each topic has 5 questions,it is firing

  • 1 for theme
  • 1 for getting topics of theme
  • (number of topics = 5) for gett‌ing all questions of a theme
  • (number of topics * number of questions per each topic = 5*5 = 25) for gett‌ing all answers of a theme
  • Total 32 queries in this case to get all answers of one theme

if 1 theme has 10 topics, each topic has 10 questions,it will fire queries,

  • 1 for theme
  • 1 for getting topics of theme
  • (number of topics = 10) for gett‌ing all questions of a theme
  • (number of topics * number of questions per each topic = 10*10 = 100) for gett‌ing all answers of a theme
  • Total 112 queries in this case to get all answers of one theme.

Using :joins will joins different tables to get required results to with selected fields. In this procedure, we can manually select all the required fields from different tables. Otherwise, there will be extra queries fired for association records.

  
questions = Question.find(:all,
  :joins => "INNER JOIN questions_topics on 
  questions.id = questions_topics.question_id",
  :conditions => "questions_topics.topic_id in 
  (#{Theme.first.topics.collect(&:id)
  .join(',')})", :order => "questions.title ASC")

It fires, below sql queries

  
questions.each{|question|question.answers.size}

fires below sql queries

active_records_tips04

if 1 theme has 5 topics, each topic has 5 questions,it is firing

  • 1 for theme
  • 1 for getting topics of theme
  • 1 for gett‌ing all questions of a theme
  • (number of questions = 25) (for gett‌ing all answers of a theme)
  • Total 28 queries in this case

if 1 theme has 10 topics, 1 topic has 10 questions,it will fire (1+1+1+100) queries total

  • 1 for theme
  • 1 for getting topics of theme
  • 1 for gett‌ing all questions of a theme
  • (number of questions = 100) for gett‌ing all answers of a theme (for gett‌ing all answers of a theme)
  • Total 103 queries in this case.

Using :include will eager load, all the associations tables into memory, along with the main table. So in this Procedure, it wont fire extra queries for association records

  
questions_with_answers = 
Question.find(:all,:include => [:answers],
:joins => "INNER JOIN questions_topics on 
questions.id = questions_topics.question_id",
:conditions => "questions_topics.topic_id in 
(#{Theme.first.topics.collect(&:id)
.join(',')})", :order => "questions.title ASC")

It fires, below sql

active_records_tips05

  
questions_with_answers.each{|question|question.answers.size}

It wont Fire any queries here.

if 1 theme has 5 topics, each topic has 5 questions,it is firing

  • 1 for theme
  • 1 for getting topics of theme
  • 1 for gett‌ing all questions of a theme
  • (number of questions = 2 quereis as we are has_many through association here) (for gett‌ing all answers of a theme)
  • Total 5 queries in this case

if 1 theme has 10 topics, each topic has 10 questions,it will fire

  • 1 for theme
  • 1 for getting topics of theme
  • 1 for gett‌ing all questions of a theme
  • (number of questions = 2 quereis as we are using has_many through association) (for gett‌ing all answers of a theme)
  • Total 5 queries in this case as well.

References:

  • http://railscasts.com/episodes/181-include-vs-joins?view=asciicast
  • http://www.fortytwo.gr/blog/18/9-Essential-Rails-Tips

Conclusion:

  • Use Collect only for collecting attributes from existing collection
  • Always better to use joins or include for fetching data from different tables or handling Associations, depending upon Requirement
  • Use include , when we need all the association table’s records along with main table
  • Use Joins, when we need to select very few Columns from different Tables.

Rails Observer Implementation Part 1

Before starting Rails Observer implementation first we quickly go through how ruby observer library is implemented.

What is Observer Pattern?
The Observer pattern (also known as publish/subscribe) provides a simple mechanism for one object to inform a set of interested third-party objects when its state changes.

require "observer"

class Foo
 include Observable
 def initialize
  add_observer(ObserveFoo)
 end
 def foo
   changed
   puts "Before Observing Foo"
   notify_observers
   puts "After Observing Foo"
 end
end
class ObserveFoo
  def self.update
    puts "Observing foo"
  end
end
Foo.new.foo
#Output
#Before Observing Foo
#Observing foo
#After Observing Foo

In above example Object of foo is observerd by ObserveFoo.

Lets walk through how it’s implemented.

add_observer methods take 2 parameters, Class/Object and method name, that invokes after notification,by default update method is called.(in ruby 1.8.7 only one parameter with update function).
In this method it adds to @observer_peers hash where key is Class/Object and value is the method name.

When Object has changed its state hen we have to notify observers.

So state can be changed by invoking changed method. This sets @observer_state variable to true.

After that we can notify by calling notify_observers(*args). This method collects all observers associated with it and invokes respective method(which is registered at the time of adding observer) with the argument ,and changes the state to false for further notification.

So in ruby it’s simple to achieve Observer Pattern in almost 3 steps.

1) Add Observer which will track all observable object
2) Change the state
3) Notify Observer which will invoke all observable object method and changed state to false for further notification.

More info regarding ruby Observer you can visit here

In next post we quickly go through Active Model observer.

I hope it helps understanding ruby observer pattern better.

Comments and feedbacks are welcome.

My experience with Vim

vimlogo

I had tried VIM in my college days but could not get hooked onto it and found it difficult to use. During my Master’s program, I tried almost all editors(Notepad++, Scite, E-text-editor and etc..). I was never into full featured IDE’s. Gedit was my first love in the editor list. I tried different plugins to make it powerful and had bumped into gmate which is a set of plugins and improvements to make Gedit a powerful programmer text editor. As I was still on a quest of finding the right IDE, I had come across blogs written on Vim. They inspired & lured me a quiet a lot but were never able to move me over to it.

I saw several developers using Netbeans, Textmate & RubyMine. I tried using those for a while and dated RubyMine for quite some time. It is surely a great IDE for ROR. However, it has a large footprint on the memory.

Vim Ego –

vim1

One day I came across a quote from Obie Fernandez which said – “Everyone knows that the best programmers use Vim and Emacs”.

Then got me started into digging more on the Vim.

Inspiration –

vim2

There is a blog by Yehuda Katz on Vim, which inspired me a lot. He interestingly mentioned using vim as you want. He OK’ed the use arrow keys instead of hjkl keys & to use a mouse. That helped to not loose productivity and very importantly kept me away from getting frustrated.

Derek Wyatt’s videos on Vim also added sugar in my Vim inspiration. If you are new to Vim I recommend you to see ‘Welcome to Vim‘ from that series. That video is just awesome.

Janus Vim –
From Yehuda Katz, I got to know about a new and very powerful way for Vim, which takes care of all my requirements for developing web applications in Ruby on Rails.
Janus is a Vim distribution of plug-ins and mappings for Vim, Gvim, and MacVim. It has almost all required features/plug-ins while programming in Rails. It includes several plug-ins likes project drawer, ctrlp (Fuzzy file, buffer, mru and tag finder), snippets and etc.
Most people ask not to use Janus, as it’s complex, opinionated and makes you lazy. But for me, it worked really well.

My steps with Vim –
Vim isn’t that hard, Two weeks are enough.

  1. Vimtutor (This tutorial helps to learn basic commands)
  2. Configuration (i.e .vimrc, .gvimrc Actually I disabled the arrow keys & GUI related goodies from the second week and forced myself to use the hjkl keys.)
  3. Went through the Janus docs to learn more commands for different plug-ins (like NERDTree, NERDCommenter, Ack and etc )
  4. Practice, Practice, and Practice

The first week was really horrible, for every small code I had to see Vim commands before writing code. It surely hurt my productivity. But as we all know ‘it takes a while to get great powers’ and one needs to be patient. After two weeks, I was able to do everything that I needed.

MUST have Plug-ins –
If you want to master Vim you have to know your config file.

My Preferences –
I tried different kinds of color schemes for Vim, but my choice is Molokai theme, you can get it from https://github.com/tomasr/molokai. If you want better-looking, more functional vim status line, then have a look on vim-powerline. It is pretty neat. Mostly I use GVim for my development, which has scrollbars and toolbar. When you creates multiple windows, you can avoid those scroll bars by adding these lines in the .gvimrc file.

  set guioptions+=LlRrb
  set guioptions-=LlRrb
  set guioptions-=T

Last but not least, I use Menlo font for coding and It looks pretty neat for eyes even at smaller font sizes.
You can download it from here.

Add this line in your .gvimrc file to set the font.

  
  set guifont=Menlo for Powerline 10

Tutorials –

 

Screen-shot

my-vim-screenshot

YAML(YAML Ain’t a Markup Language)

As the meaning of YAML its not markup language which could be used for communication between 2 components like while you are doing webservices and such. It is a mechanism to serailize data and use it accross your app. Ruby on Rails is a super example of how you could use it in the right way(database.yml). One tends to generally use for storing application level configurations (Like a properties file in Java but more readable and idomatic for me atleast). There are readymade parses available in languages like Ruby, Java, Perl, Python etc.

I would make sure to create a singleton object for your configuration as IO operations are expensive. Below are a few tips and tricks that I use regularly while manipulating configurations in using a yml file. It starts with basics and goes a little advanced (IMO, there is nothing so advanced though).

Basics:

username: 'someservice'
password: 'passme'
allowed: 5
....

the above assigns a basic key, value pair

grades:
  - 'A'
  - 'A-'
  - 'B+'
  - 'B'
  ...

array of grades. Sequences can also be defined as:

grades: ['A', 'A-', 'B+' ....]

Hashes:

companyaddress:
  street1: '100 W Hubbard'
  ...
  city: 'New York'
  state: ....

The above essentially means a element company address having a hash with k,v
companyaddress => {‘street1’ => ‘100 W Hubbard’, ‘city’ => ‘New York’}

Environment Specific:
This is so intuitive. If you need a set of values specific to the environment, you achieve it with almost no hastle:

defaults: &defaults
  correspondence_address:
    street1: '100 W Hubbard'
    ...
    city: 'New York'
    state: ....
development:
  <

What the above means is if you need a correspondence_address then its common in all environments where as; the billing_address could be fetched per environment(Obviously you will need some manipulations after you read the file to fetch the env specific values).

A little advanced:
A beautiful thing about YAML is aliases and references. Its like variabalizing your constants.
An alias is defined by &alias_name for example:

address: &address
  street1: '100 W Hubbard'
  ...
  city: 'New York'
  state: ....
  ....

A reference is accessed by *alias_name for example:

billing_address:
  <<:*address
shipping_address:
  <<:*address

The above means the shipping address and the billing address gets the values of address. Its like merging 2 hashes. An array can also be through references.

- &pass_grades
  - 'A'
  - 'A-'
  - 'B+'
  - 'B'
  ...
- &fail_grades
  - 'D'
  - 'F'
primary_school_grades:
  - *pass_grades #you will flatten the array to get the grade values
secondary_school_grades:
  # Again you will flatten the array to get the grade values
  - *pass_grades 
  - *fail_grades

Thus, if you have to add a third entry for grades for lets say a ‘high_school_grades’. You would just use the references for ‘pass_grades’ + ‘fail_grades’ like we do in the above example.

Ruby/Rails specific:
Below is just a mix of examples that I have found googling and used in my rails projects(its a real monster yeaahhh!!!).
For example, you want to add a email validation in your rails application and need a regex for it here is how you could do it.

email_regex: !ruby/regexp '/^([w.%+-]+)@([w-]+.)+([w]{2,})$/i'

You could also use erb expressions, obviously you need to take care of the dependencies.

development:
  cache_ttl: <%= 60.seconds %>
production:
  cache_ttl: <%= 60.minutes %>

References that might help:
http://en.wikipedia.org/wiki/YAML
http://yaml.org/YAML_for_ruby.html(for rubyists)

I will keep updating this blog as I learn more. But I hope the 3 minute read would have helped. Feel free to send opinions, examples and tricks through your comments.

Subscribe To Our Blog

Get access to proven marketing ideas, latest trends and best practices.

Next up home

Contact

Lets build cool stuff

Share your contact information & we will get in touch!

I want (Tell us more about your dream project)