But know what Rails is an awesome framework, you can ensure that the table names are not pluralized with a single configuration line in your project's environment.rb file.
November 25, 2011
Prevent rails from pluralizing table names
But know what Rails is an awesome framework, you can ensure that the table names are not pluralized with a single configuration line in your project's environment.rb file.
Rails 3 and its Sandbox
Rails console has always been a friend in need for the Rails developer. More often, we get to the console to try out some coded snippets to verify and validate our assumptions, either while writing the test cases or during the coded implementation. In this process it is very likely that we end up modifying the state of the underlying database. This inturn can cause some headaches or frustration. Nonetheless you soil the database with junk data. If you are fine with it, then read no further - this post is not for you. If however you are wondering for a way to SANDBOX your play environment from soiling the database, then read on.
Run your console with the command as below:
$ rails c --sandbox
That is all you need to do to maintain the sanity of your undedrlying database.
So what does this sandboxing do? It keeps journaling all the activities that you do on the database and will undo it all upon exit so that the database goes back to the state previous to sandboxing.
There are some implications however to working this way though. If you were to run the sandbox on say, development database, then you wouldn't be able to run your DB migrations on your database while the --sandbox is on. Oh!, in fact you wouldn't be able to modify the state of the databases in any manner, be it insert / update / delete records. When you attempt to do it, you would see that the DB throws an error message that reads something as below:
ActiveRecord::StatementInvalid: SQLite3::BusyException: database is locked: ...
November 19, 2011
Miniature Code Retreat
I was so excited with the idea of Code Retreat invented by Corey Haines, that I pushed for conducting a miniature version it (with just two sessions of pair-programming) at Dev Camp Chennai, 2011.
My Goal of conducting a Mini Code Retreat
- First and foremost, my agenda was to market the Global Code Retreat that is to happen on the December 3rd of 2011.
- There are very few corporates that follow TDD, pairing and "refactoring". If folks who can participate in the session, get a good hang of and appreciations for it all, then they would well become agents to market the experience of good practices.
- Its been a long while since I facilitated. I personally wanted to see where I stand in facilitation and see what I derive out of this session as a facilitator.
What I did to achieve my goals
- Dev Camp was a good crowd puller and I wanted to use that occassion to ensure that I give people the taste of what really Code Retreat is all about. Soon after my welcome address, I did a quick poll of how many know of the Code Retreat event that is to happen two weeks from now and then gave an introduction to Code Retreat (early marketing).
- Kept reading different blog posts etc sharing the code-retreat conduct and facilitation experience, lessons etc.
- Not many folks had a laptop with them in the DevCamp. This was really unfortunate. Made an announcement that only folks with laptop have a entry pass, to the code retreat event. This sort of disappointed the really interested few, some of whom approached me post my introduction. Touched by the enthusiasm, I had arranged for three laptops with the required things setup.
- In the very beginning, I decided to pair-up with someone who is very earnest and equally passionate as much as I was. And I did pair-up with my friend and fellow comrade Ponnulingam, who did all the work that is required to ensure that the laptops are all set-up with necessary SDKs, IDEs, base project set-up with a unit-testing framework.
- At the start of the code retreat session , we set the ground rules, the dos and the don'ts.
- Gave the classical Mars Rover problem of ThoughtWorks Recruitment to attendees. I choose this problem (with the due permissions from the Recruitment team's lead, Manish), over anything else because the problem is very straightforward. This gives the coders a good opportunity to focus on the ground rules, pair-programming experience, TDD approach and stuff, instead of being distracted to spend endless time discussing the problem statement. Though honestly, I realized they were trying to the same until I was parroting the mantra a few times to stop discussing too much of details, and start coding ASAP after the first 3 minutes. In 5 minutes time, every one started coding.
- Swap pairs after every round.
- Conduct of retrospective at the end of the session helped folks to learn from others goodness/mistakes. It gave them a renewed sense of energy and interest.
Results
- In just two session, it was nice to hear from folks who experienced the joy of TDD (test first/driven development).
- Everyone but for just a single pair weren't comfortable pairing in every session. Interestingly enough, the pairs that reported this were entirely different. I realized in in both these occassions, one of them took things very personally by their stride, and also that they broke the very basic ground-rule of deleting the older coded (the pair that had written the code hung to it and was trying to enforce the further development on the existing code). I wish, I had caught this while I was moving from pair to pair to check on what they do - good and bad, by the time I reached this pair I was only thinking that they had progressed that far.
- As pair facilitators, we decided to rope in another pair to help us out in facilitation, and that really helped. I believe understanding the maturity/skills level of coders is very very important for better facilitation. If the majority find the terms - TDD, pair-programming, refactoring - very new but something that they have heard of and are extremely curious to know it all in one gulp, you need more folks who could get them settled quickly.
- Many felt that they were better able to understand the problem statement as result of pairing.
- There were a few who felt that while at the very beginning they were not so comfortable pairing with experience programmers, became very confident by the end of the session as result of picking up skills from their experienced peer and practice it in their presence while pairing.
- Most of them felt pairing increased their productivity, because they weren't lost in their thoughts and thinking out loud with their pair benefitted them clearly.
- Folks left the room with a sense of enlightened joy, saying they would come again to experience the learning again at Code Retreat.
- In second round, good half of the coders became self-disciplined to TDD. I find this interesting.
- We concluded the Code Retreat with a retrospective, in which we asked people to provide anonymous feedback on their experience of the Code Retreat session in entirity. We split the board into three pies - "What went well?", "What didn't go well", "Puzzles". Once everyone left, my curius eyes went to the Not-well section and found just TWO single-worded sticky(s) with "nothing" scribed in it. Not sure if they meant, there was nothing that didn't go well or that they have gained nothing which isn't well. I read it as the later.
@kartzontech loved the sessions..looking forward to sessions like these...
— sivaramom (@sivaramom) November 19, 2011
Pictures of the Code Retreat session can be seen here.November 12, 2011
Agile Tour 2011, India
Agile Tour 2011, India @ Chennai on 12-November-2011
I had the opportunity to give two extempo lightening talks to the people at this conference. The topics were, "The attitude that an individual and team has to carry when the CI build breaks" and "Planning is important but plans are not". I felt compelled to share my experience and thoughts on those topics, because I observed that the delegates were discussing about it more and wanted more clarity.
How my talks were received?
Oh I guess, it was well received as many could understand and appreciate it prompting them to talk and ask more questions about Agile post my talks. I doubly enjoyed it, because there were both developers and management folks equally interested to learn more and more by way of discussing things in their mind with me.
Secondly, Preethi Madhu, ThoughtWorks India, Head of Consulting, was happy to provide a very positive feedback to me. Thanks Preethi :)
May I request your feedback on my talks?
If you have attended/participated-in my talk and discussions thereafter,...and have something to share, then please feel to put yout thoughts across by way of comments to this blog post.
Also, if you have published any photographs of the event, please do share them in the comments section and I shall make a reference to it all by posting the links in this blog post.
Update: The pictures of the even can be found in FaceBook.
October 30, 2011
Vim for Rails Developer
Every person gives feedback based on his understanding of things which is dependant on his level of skills at that point in time. For the reader of this post, who is interested in knowing my background to better evaluate my feedback, I have elaborated in brief my history of experience in the RoR world of application development.
After spending about 10 months in my first JRuby on Rails-2, two-developer all-chaotic first non-pairing project, where I was using RubyMine as IDE for all practical development purposes, I resolved to try out a new IDE in my next Rails gig. Folks at ThoughtWorks are in the habit of experimenting and trying out different IDEs. And hey, I was no exception ;) - prior to RubyMine, I tried Vim and Aptana RadRails, but for whatever reason I loved RubyMine, perhaps because I was too familiar with this one by virtue of my experience of using IntelliJ in Java projects.
As decided I did choose a new IDE when I moved on to my second RoR3 gig and it was Vim. Why Vim? Well, apart from it being extremely lightweight when compared to its counter-parts, I seriously wanted to get a hang of this IDE, as many RoR developers at our office either use TextMate or Vim (by stats more Vim fans). Okay so did I step into this very small and demanding project of just two developers (including me) that were notably enough not pairing (again!). What does that mean? It means I have to constantly explore to figure out the stuff that is required to become more and more conversant and productive with Vim (atleast as much I am with RubyMine). If you have gone through my experience you'll understand how steep a learning curve it is to get an appreciation of Vim for Rails productivity (even while learning Rails 3, argh!).
Now, I have moved on to my third RoR3 gig with 3-4 dev-pairs (ho-ho pairing again, after real long time!), where-in I guess all are Vim-ites. Its been a couple of days, and I see people use many productive plugins for Vim. Delighted!, my learning curve is going to get better.
In the mean time, I had requested Ben Orenstein, for a free copy of screen cast titled, "Vim for Rails Developers" that he authored. In return, I promised to write a candid review of his screen cast on my blog. I fulfill my promise with this blog post wherein I share my thoughts/experience of the said screencast. Now, the way I share my thoughts is by dissecting the portions of screen cast, and tell you what to expect from each of it. [pause] So, in the mentioned screencast, Ben has covered the following sections in bold:
Fast Typing:
- Do you think, 80 words per minute is okay? Listen to him.
- play.typeracer.com => How this site helps the enthusiast hit Bens's objective of "Speed with ********"
Vim Cheat sheet:
- viemu.com => I have many a times visited and downloaded this cheat-sheet from this site, but didn't really care to read it seriously. His talk I guess insisted well on what to look out for in this cheat sheet :)
Dvorak Simplified Keyboard
- Learn to touch type.
- I haven't heard this anytime before. I gotta know about this in this screen cast.
- This is the only section that did not fascinate me, perhaps because I did not see him demonstrate its usefulness.
Rails.vim
- An intro on how to use it. He gave a real good shot at it, helping me understand that he did his best given the size of this huge plugin. Keep digging and you get more and more wealth of short-cuts!
- If you haven't used this plugin, his intro will seed the interest in you to try and have fun with this plugin.
- Try this in your Vim command-line: :help rails => for rails-vim documentaion
Snipmate: Mac's Textmate style snippets for Vim
- It supports Rails
- Where to look for your favorite language's snippets that snipmate supports [Note: ~/vim/snippets/]
- How to add your own snippet
The power of Tags
- Exuberant CTAGS: CTags creates an index on where the class, methods, instances are defined. This helps the developer big-time in jumping from say, method usage to its definition. Intelli-sense of sorts, eh!
- How to use CTags?
- How CTags help?
Ack
- Get it right. Its Ack, not awk! Its a grep replacement tool, designed for programmers. Can't believe the funda? Well, I too didn't until I watched him play in this screencast.
Quick one-offs
- Bunch of other enlightening surprises... :) By the time you reach here, you won't feel like skipping this section, for you'll quickly come to an understanding that this is not some miscellaneous stuff but the quick wins that you get to learn while you are playing with Vim.
For many, "seeing is believing". And I fall very much in that category. Thus, this screencast had a very good impact on me and so shall it on you ;) You can't ask for more in a screencast that is approximately 37 minutes long.
I'll heartily give him a 4.5/5 as rating for this screencast, for the good breadth and fair depth in content that he has both covered and demo-ed, in a manner that inspired me to kick myself harder to learn and get used to the stuffs/tools that he mentioned.
Thanks to Ben, for an awesome introduction through live demo to the various tools that he uses for his every-day rails programming. Personally though, I wish wish wish, he touched upon the other productivity plugins too, if he were to use any. Don't know if I'm being greedy here!
Lastly, if you wish to watch this screen-cast, and that you are put up in Chennai, don't miss the DevCamp,Chennai happening this November 19th at ThoughtWorks Technologies Ltd, Ascendas IT Park, Chennai, Tamil Nadu, India. This screencast is making an entry, and if voted for by many (as like any other in-person session), it will be put up. Come vote, watch and get enlightened!
October 21, 2011
Leveraging Subject in RSpec - A rough cut!
The better way to write the above test is as below:
Further refactoring the above code snippet, it can be compacted to below, although I hate to do this. I prefer to tests/specs being an utter no-brainer to read quickly and get the idea:
Finally the ideal way of testing the above scenario and the like would be to employ RSpec's subject as below:
If after reading all this you were to wish it be more leaner, then you should consider shoulda. Will blog about it's marriage with RSpec sooner ;) Until then see how snappier the above code becomes with the use of shoulda matchers. Hooray!!!
SQL Logging in Rails Console IRB
In order to quickly find the SQL queries that are fired against the DB, while you are playing on the Rails Console, all you need to do is set ActiveRecord's Logger to STDOUT as below:
>>ActiveRecord::Base.logger = Logger.new(STDOUT)
Custom finders and SQL Injections
[ERROR] couchapp error: You aren't in a couchapp.
Every CouchApp must have a .couchapprc file in the application directory. This file is a JSON object which contains configuration parameters that the command-line app uses to build and push your CouchApp.
The couchapp generate and couchapp init commands create a default version of this file for you.
If you don't have a .couchapprc file, couchapp will display the dreaded couchapp error: You aren't in a couchapp message.
September 21, 2011
Can't find first MyFreakingActiveRecordModel
Lesson: Shoulda requires a record in the DB, well atleast in this case :P
September 6, 2011
Rails 3 - Filtering Sensitive Parameters From Being Logged
A sample Rails3 config file having this setup will look as below (MyRails3App is the name of my rails application):
September 3, 2011
Untrack a file in Git
The story in detail...learning by experience
[practice]$ mkdir myproject
[practice]$ cd myproject/
[myproject]$ git init
Initialized empty Git repository in /home/karthik/MyRubyProjects/practice/myproject/.git/
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add
#
# abc.txt
nothing added to commit but untracked files present (use "git add" to track)
Situation 1: If you were to untrack a newly created file that you added to staging for commit.
[myproject(master)]$ git st
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached
#
# new file: abc.txt
[myproject(master)]$ git rm --cached abc.txt
rm 'abc.txt'
[myproject(master)]$ git st
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add
#
# abc.txt
nothing added to commit but untracked files present (use "git add" to track)
[myproject(master)]$ git st
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached
#
# new file: abc.txt
[myproject(master)]$ git commit -m "Commit abc.txt"
[master (root-commit) a67174c] Commit abc.txt
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 abc.txt
[myproject(master)]$ git st
# On branch master
nothing to commit (working directory clean)
[myproject(master)]$ git st
# On branch master
# Changed but not updated:
# (use "git add
# (use "git checkout --
#
# modified: abc.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
rm 'abc.txt'
# On branch master
# Changes to be committed:
# (use "git reset HEAD
#
# deleted: abc.txt
#
# Untracked files:
# (use "git add
#
# abc.txt
With that result, let us call it a day ;)
June 22, 2011
Kill process listening/bound to specific port
Step 1: Identify the process
For this you can use either of the command below:
lsof -w -n -i tcp:<port_number>
where,
-w implies suppression of warning messages
-n option inhibits the conversion of network numbers to host names for network files. Inhibiting conversion may make lsof run faster. It is also useful when host name lookup is not working properly.
-i[i] option selects the listing of files any of whose Internet address matches the address specified in i. If no address is specified, this option selects the listing of all Internet and x.25 (HP-UX) network files.
If -i4 or -i6 is specified with no following address, only files of the indicated IP version, IPv4 or IPv6, are displayed. (An IPv6 specification may be used only if the dialects supports IPv6, as indicated by "[46]" and "IPv[46]" in lsof's -h or -? output.) Sequentially specifying -i4, followed by -i6 is the same as specifying -i, and vice-versa. Specifying -i4, or -i6 after -i is the same as specifying -i4 or -i6 by itself.
Multiple addresses (up to a limit of 100) may be specified with multiple -i options. (A port number or service name range is counted as one address.) They are joined in a single ORed set before participating in AND option selection.
An Internet address is specified in the form (Items in square brackets are optional.):
[46][protocol][@hostname|hostaddr][:service|port]
where:
46 specifies the IP version, IPv4 or IPv6 that applies to the following address. '6' may be be specified only if the UNIX dialect supports IPv6. If neither '4' nor '6' is specified, the following address applies to all IP versions.
protocol is a protocol name - TCP or UDP.
hostname is an Internet host name. Unless a specific IP version is specified, open network files associated with host names of all versions will be selected.
hostaddr is a numeric Internet IPv4 address in dot form; or an IPv6 numeric address in colon form, enclosed in brackets, if the UNIX dialect supports IPv6. When an IP version is selected, only its numeric addresses may be specified.
service is an /etc/services name - e.g., smtp - or a list of them.
port is a port number, or a list of them.
Sample Command Line Output:
karthik@cloud:~/MyRubyProjects/dashboard$ lsof -w -n -i tcp:3000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ruby 2969 karthik 5u IPv4 68913 0t0 TCP *:3000 (LISTEN)
Alternatively, you may use the command below:
netstat -anp | grep :<port_number>
where,
-a displays all active connections and the TCP and UDP ports on which the computer is listening.
-n displays active TCP connections, however, addresses and port numbers are expressed numerically and no attempt is made to determine names.
-p Linux: Process : Show which processes are using which sockets (similar to -b under Windows) (you must be root to do this)
Sample Command Line Output:
karthik@cloud:~/MyRubyProjects/dashboard$ netstat -anp | grep :3000
(Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.)
tcp 0 0 0.0.0.0:3000 0.0.0.0:* LISTEN 2969/ruby
Step 2: Kill the process
kill -9 <procecss_id_number>
Eg:
karthik@cloud:~/MyRubyProjects/dashboard$ kill -9 2969
June 20, 2011
When you see Gem error like - "'': uninitialized constant Gem::SilentUI (NameError)"
I just created a new Rails 3 project called dashboard and tried having bundler install all the required basic gems for this project using the command - bundle install. Damn!, I got the error that is the title for this blog post.
Below is the snap shot of the command and the error:
karthik@cloud:~/MyRubyProjects/beach_projects/dashboard$ bundle install
/home/karthik/.rvm/gems/ruby-1.9.2-p0@rails3/gems/bundler-1.0.7/lib/bundler/ui.rb:56:in '<class:UI>': uninitialized constant Gem::SilentUI (NameError)
from /home/karthik/.rvm/gems/ruby-1.9.2-p0@rails3/gems/bundler-1.0.7/lib/bundler/ui.rb:2:in `<module:Bundler>'
from /home/karthik/.rvm/gems/ruby-1.9.2-p0@rails3/gems/bundler-1.0.7/lib/bundler/ui.rb:1:in `<top (required)>'
from /home/karthik/.rvm/gems/ruby-1.9.2-p0@rails3/gems/bundler-1.0.7/lib/bundler/cli.rb:16:in `initialize'
from /home/karthik/.rvm/gems/ruby-1.9.2-p0@rails3/gems/bundler-1.0.7/lib/bundler/vendor/thor.rb:246:in `new'
from /home/karthik/.rvm/gems/ruby-1.9.2-p0@rails3/gems/bundler-1.0.7/lib/bundler/vendor/thor.rb:246:in `dispatch'
from /home/karthik/.rvm/gems/ruby-1.9.2-p0@rails3/gems/bundler-1.0.7/lib/bundler/vendor/thor/base.rb:389:in `start'
from /home/karthik/.rvm/gems/ruby-1.9.2-p0@rails3/gems/bundler-1.0.7/bin/bundle:13:in `<top (required)>'
from /home/karthik/.rvm/gems/ruby-1.9.2-p0@rails3/bin/bundle:19:in `load'
from /home/karthik/.rvm/gems/ruby-1.9.2-p0@rails3/bin/bundle:19:in `<main>'
What is the issue? The issue is perhaps with the version of bundler and its dependencies. To resolve this issue, I ran the gem update for the bundler and know what? It worked ;)
Below is the snap shot of the command and the output:
karthik@cloud:~/MyRubyProjects/beach_projects/dashboard$ gem update bundler
Updating installed gems
Updating bundler
Fetching: bundler-1.0.15.gem (100%)
Successfully installed bundler-1.0.15
Gems updated: bundler
After this I tried running the "bundle install" command and the required gems were installed successfully.
Below is the snap shot of the command and the output:
karthik@cloud:~/MyRubyProjects/beach_projects/dashboard$ bundle install
Fetching source index for http://rubygems.org/
Installing rake (0.9.2)
Using abstract (1.0.0)
Using activesupport (3.0.3)
Using builder (2.1.2)
Installing i18n (0.6.0)
Using activemodel (3.0.3)
Using erubis (2.6.6)
Installing rack (1.2.3)
Installing rack-mount (0.6.14)
Installing rack-test (0.5.7)
Installing tzinfo (0.3.28)
Using actionpack (3.0.3)
Using mime-types (1.16)
Using polyglot (0.3.1)
Using treetop (1.4.9)
Installing mail (2.2.19)
Using actionmailer (3.0.3)
Installing arel (2.0.10)
Using activerecord (3.0.3)
Using activeresource (3.0.3)
Using bundler (1.0.15)
Using thor (0.14.6)
Using railties (3.0.3)
Using rails (3.0.3)
Using sqlite3 (1.3.3)
Using sqlite3-ruby (1.3.3)
Your bundle is complete! It was installed into /home/karthik/.rvm/gems/ruby-1.9.2-p0@rails3
- All of above commands and its output can be found here => https://gist.github.com/1035387
June 17, 2011
How to find the method definition - one that is invoked at runtime?
During the QnA session after my talk at RubyConf India 2011, one avid Ruby enthusiast asked me a question, "How to find the method definition - one that is invoked at runtime?".
I confessed that in all my experience (for the last eight and odd months) with Ruby, I have been doing the grep-ing for the method name and then figure out which method definition would be the last to over-ride every other ones declared earlier. No sooner did I finish answering, boooooooooom came a greatly handy tip from a very respectable and renowned geeky person in the crowd - Ola Bini. He adviced to use Ruby's "method" method to figure out the source of the method that was invoked at runtime. What an easier and neater approach!
Hearty thanks to both the folks - one who questioned and the other who answered.
This blog post is my attempt to elaborate more on the tip that Ola Bini had adviced.
Back home after the conference, I googled on these lines and found the following resources useful (in fact, this blog post is only my assimilation of these). May you find them useful.
Additional resources of interest:
- Programming Ruby 1.9: The Pragmatic Programmers' Guide (Facets of Ruby)
- Metaprogramming Ruby: Program Like the Ruby Pros
June 7, 2011
Ruby Conf India 2011
I happened to be one of the speakers in this international conference that was held at Bangalore. What pleasure and privilege! The subject of my talk was Deciphering the Ruby Object Model, aimed to help fellow ruby enthusiasts level up their understanding and appreciation of Ruby as a programming language. The talk was well received by many a folks who had attended my session. I wish to thank every one who had personally come over to me for sharing their feedback with me.
You can download the presentation from any of the below mentioned locations:
- Slideshare (PPT version only)
- RubyConfIndia (Both PPT and PDF versions available here)
Deciphering The Ruby Object Model from Innovation & Technology Trust on Vimeo.
For all the positive feedback I had received, I intend to very soon publish a couple of blog posts detailing on specific areas of interest. If you have attended my talk and wish I write up a blog post or two on specific areas please do feel free to communicate it via comments to this blog post and I shall make my humble and sincere attempts to dispell some of the confusion and enlighten you in that area.
Any other feedback that you would like to share is also welcome ;) You may always use the comments section of this blog for this purpose.
A few sites or blog posts that did have a mention of my talk or appreciations/criticism for my talk are put listed below. They'll be my motivation to move forward - further and faster!
- Ruby Conf 2011 India - Day 1 Summery via rtdptech.com
- Ruby Conf India 2011- The good, bad and the ugly
- A live blog of Ruby Conf India 2011 via Binay Doodles
Some live tweets while I was delivering my talk can be found below:
Interfaces (Java/C# concept) are irrelevant in Ruby... coz of duck-typing.. @kartzontech #rubyconfindia
— Prakash Murthy (@_prakash) May 28, 2011
another_statement = "@kartzontech is bullshitting at #rubyconfindia" another_statement.really? => NoMethodDefined error Good example :-)
— Prakash Murthy (@_prakash) May 28, 2011
Launch was ok . Attending @kartzontech talk #rubyconfindia
— shardul mohite (@shardulmohite) May 28, 2011
As I have mentioned in my talk, the following books should be a part of your reading book-shelf if you are serious about programming in Ruby:
May 7, 2011
... the gem has no specification file. Run 'rake gems:refresh_specs' to fix this.
Did you happen to vendorized gem and get a warning message like, "... the gem has no specification file. Run 'rake gems:refresh_specs' to fix this."? Afterr looking at the warning message did you try running the suggested rake command - rake gems:refresh_specs - to no avail? What next? How the heck do I get rid of this warning message?
Well, in times when gems for some reason doesn't vendorize the requisite specification file for that vendorized gem. You may have to run the following command in the respective gem's vendorized directory:
gem specification gem_name_without_version_number > .specification
Here is an example of my case wherein, I vendorized the factory girl post my installing it in my gemset and tried running the server. I got a warning message as below:
config.gem: Unpacked gem factory_girl-1.3.3 in vendor/gems has no specification file. Run 'rake gems:refresh_specs' to fix this.
kartz@desktop:~/MyRubyProjects/my_project$ cd vendor/gems/factory_girl-1.3.3/
kartz@desktop:~/MyRubyProjects/my_project/vendor/gems/factory_girl-1.3.3/$ gem specification factory_girl > .specification
After this I tried running the server or any rake task, and yeah as told earlier the warning message vanished....
April 20, 2011
How to disable gnome-ssh-askpass?
Today we had setup Git repo with access to it through corporate's LDAP authentication. From the client machines we can access it using the .netrc (where the machine, login and password are configured).
However, for some wierd reason, upon trying to pull/push commits from/to the Git repository, the bash shell tries to open the gnome-ssh-askpass dialogue and it fails. I wanted to prevent the bash shell from attempting to launch the dialogue box. To do this, all I had to do is run the following command in the terminal:
$ unset SSH_ASKPASS
To prevent it in future, you can add the above line in your .bashrc or .bash_profile.
Wish you trouble-free working!
No DHCPOFFERS received. No working leases in persistent database - sleeping.
I was getting this weird error "No DHCPOFFERS received. No working leases in persistent database - sleeping.", when trying to connect to internet via WIFI in Ubuntu.
After enough googling to no avail, and by sheer serendipity I solved this. This worked for me; may be it helps you too.
Argh, I missed the point. So here is what you can try if you are stil having this issue.
Step 1: Go to, System -> Preferences -> Network Connections
Step 2: Select Wireless tab
Step 3: Click "Edit" the wifi connection profile you have created
Step 4: There are two connection modes - Ad hoc and Infrastructure. Choose the "Infrastructure" mode
Step 5: Save and try connecting again. You are done...!
April 3, 2011
GVim, Vim, Vi key-board short-cuts
- Switch between tabs
Ctrl+PageUp, Ctrl+PageDown
Ctrl + Shift + UpArrow, Ctrl + Shift + DownArrow
- Move to Nth tab in gvim
- Open a file in new tab from NERDTree while still remaining in NERDTree
T will open the selected file in new tab, without changing focus from NERDTree
t will open the selected file in new tab, and changes focus to that tab
- Recursively Open all child nodes
Activate the NERDTree and navigate to the directory whose all child nodes must open.
Now press O (capital) to expanded list of child nodes
- Recursively Close all child nodes
Activate the NERDTree and navigate to the directory whose all child nodes must close.
Now press X (capital) to collapsed list of child nodes
- Close all tabs at once with a single command, when I have multiple tabs open
If no files are modified, then
:qa
To save work in all tabs and exit, then
:wqa
:xa
To close all other tabs, except the active one:
:tabo
To close all tabs and open buffers
:qall
:tabdo :q (The :tabdo will execute the command passed to it - in this case :q - for all the open tabs)
- Text object selection
Select text between Paranthesis block ()
When cursor is within the Paranthesis block (), type vib
Select text between Curly braces block ()
When cursor is within the Curly braces block (), type viB
Note: To make the selections "inclusive" of quotes, parenthesis or braces you can use a instead of i
More on this can be read at Text object selection
- Create a file or directory in NERDTree
- Rename a file or directory in NERDTree
- Start VIM with NERDTree opened automatically
- Auto-open NERDTree in every tab
March 31, 2011
Consolidating DB migration in Rails
In my current project we used to maintain a good number of rails migration scripts until, one guest developer stepped into the team for a short while and shared his knowledge on consolidating Rails DB migrations which I intend to blog about in this post.
So what is consolidating DB migrations all about? So if you have the DB migrations say, 1_aaa.rb, 2_bbb.rb and 3_ccc.rb that has gone into your production release 1.00, post your successful release (or a day or two after that), you can consolidate the scripts to something, say 3_consolidated_migrations.rb, wherein this new script essentially borrows the id (here it's 3) from the last run migration in production release and the contents being the same as schema.rb
So what are the implications of this? Well you need to keep in mind of the following:
- Without this approach being adopted, we can just about run the DB migrations on DB dump irrespective of its snapshot date. To put it other way, adopting this practice implies that you'll necessarily have to get the snapshot of Production DB that is no behind the release - say, if you have made released v3, then the DB snapshot has to be after release v3 is made successful.
- If you had written data migration scripts, say from a table1.column1 to table2.column2, these would be lost. However, is there a point of having them in the scripts beyond successful release to production? In most of the occassions, your answer will be NO. However, if you have a compelling reason to have such data migration scripts in Rails DB migrations, then you may not choose DB consolidation.
- This one is very important to reckon with. If your DB migrations have scripts related to DB constraints - primary and foreign key, then all these will be lost with DB Consolidation, as we don't have rails api that is DB agnostic. As a work around you may maintain these scripts in separate DB specific .sql file - something like oracle_db_constraints.sql. In our project, whenever we had to introduce this kind of constraints, we had it both in DB migrations script specific for that release and add the same to the list of SQL(s) in the .sql file(s) that we maintain separately.
- Some Rails team adopt the practice of including scripts for seed data insertion, in the db migrations scripts. This will be lost with DB consolidation, which in my opinion is a good one because it then forces the team to have a seperate file for this purpose (remember 'Seperation of Concerns' here). The other approach is to exclude this specific migration file from DB consolidation code based on this file pattern, which in my humble opinion is not bad thing.
March 30, 2011
tar command (with compress option)
February 9, 2011
No more cron jobs. Schedule jobs through rufus-scheduler in rails.
In the project that I'm working currently, I was asked to look out for ways to replace the scheduling jobs through crontab in favour of some scheduler that can control/schedule run the tasks at regular interval as long as the application is up and running. Thanks to my comrade in Dev-Ops team (Ranjib Dey) who directing my attention to rufus-scheduler.
rufus-scheduler - Things can't be simpler! Let us see how simple it is in action with a sample code
First step to usage is install the gem; so, find below the command for the same. You run it from the root of your application folder and I assume that you use rvm (if not, prefix the command with - sudo )
> gem install rufus-scheduler
Now, when the rails application gets kick-started, it reads all .rb files under config/initializers directory as part of its initialization process. This step in rails start-up, is what we'll take advantage of. So, let us create a new file, say my_tasks_scheduler.rb, in config/initializers directory.
<my_rails_app>
| -- app
| -- config
| -- initializers
| -- my_tasks_scheduler.rb
| -- db
| -- ...
| -- ...
| -- lib
| -- tasks
| -- tempfile.rake
The contents of the file my_tasks_scheduler.rb would be like:
require 'rufus/scheduler' # Need this to make use of Rufus::Scheduler
require 'rubygems' # Need this to make use of any Gem, in our case it is rufus-scheduler
require 'rake' # Need this to make use of Rake::Task
# 'tempfile.rake' is the rake file I had defined under lib/tasks directory in my rails application
load File.join(RAILS_ROOT, 'lib', 'tasks', 'tempfile.rake')
# 'misc.rake' is the rake file defined under railties/lib/tasks directory of the installed rails version that your application makes use of.
# 'misc.rake' is not required to be loaded if none of your rake tasks that you invoke are dependent on :environment task, directly or indirectly
# If this file is not loaded, you would see an error message like "Don't know how to build task :environment"
load File.join('lib', 'tasks', 'misc.rake')
# OPTION 1: If you want to run the scheduler as part of your very own rails process then you may adopt this option
temp_files_cleaning_scheduler = Rufus::Scheduler.start_new
# Making use of the syntax used in Crontab
temp_files_cleaning_scheduler.cron '*/1 * * * *' do
task = Rake::Task["tempfile:delete_all"]
task.reenable # If only you do this, will your rake task run the next time you invoke it.
task.invoke
end
#OPTION 2: If for whatever reason (say, for performance reasons) you want to run your rake tasks as seperate process independent of your rails application, then you may adopt this option
temp_files_cleaning_scheduler = Rufus::Scheduler.start_new
#Making use of a more intutive approach, instead of Cron syntax
temp_files_cleaning_scheduler.every "1m" do
# Programmatically, kick-starting the rake task from the command line
system "rake tempfile:delete_all RAILS_ENV=#{RAILS.env}"
end
And that is it, you are all set for action...
Additional references that are worth reading are mentioned below:
- Rufus Scheduler home page
- Dead simple task scheduling in Rails
- Rake tutorial by Jason Seifer
- Custom Rake Tasks by Railscasts
- Jay Fields' thoughts on testing rake tasks
- John Barnette on Rake
- Questions in StackOverflow
February 1, 2011
Externalizing ALL application specific configurations to a file outside of Rails ROOT
The application that I'm having in my mind is an internal rails application that gets deployed in an internal hosting environment instead of hosting it in a external environment like Heroku, etc.
Follow through the self-explanatory code snippets to get an understanding of how I achieve it in simple way. For the noobs, the quick explanation would be that the code snippet in environment.rb file reads the YAML file from system to copy all key value pairs to Rails' ENV hash. This ENV hash is available everywhere while/on/after application load.
I'm a wannabe reader for the book,
January 25, 2011
Run SQL in Unix Shell
Now back to my business of curiosity - I wanted to know how do I do this in every other databases that I have used so for. This blog post is a record of that endeavor. This should be very handy mainly for the Rails developers.
Unix, SQL and SQlite3
linux_prompt$ sqlite3 db_file_name.sqlite3 "SELECT * FROM my_db_table"
linux_prompt$ sqlite3 db/development.sqlite3 "SELECT count(*) from schema_migrations"
linux_prompt$ sqlite3 db/development.sqlite3 <<EOF
> SELECT * FROM users; --where 'users' is a table in my development.sqlite3 DB
> SELECT * FROM schema_migrations; --where 'schema_migrations' is a table in my development.sqlite3 DB
>EOF
Unix, SQL and MySQL
linux_prompt$ export username="dbuser"
linux_prompt$ export password="dbpassword"
linux_prompt$ export db="mydatabase"
linux_prompt$ mysql -u "$username" -p "$password" "$db" <<EOF