Ruby on Rails blog, scripts, tips

actsasblog Ajit's blog

   Nov 13

Demeter Law

Following link made it so easy to understand the Demeter Law:

  • You can play with yourself.
  • You can play with your own toys (but you can’t take them apart),
  • You can play with toys that were given to you.
  • And you can play with toys you’ve made yourself.

http://devblog.avdi.org/2011/07/05/demeter-its-not-just-a-good-idea-its-the-law/


   Mar 21

Reset ID sequence on Postgres database using Rails

If you ever need to reset ID sequence of a Postgres database with rails then following command is your friend:

ActiveRecord::Base.connection.reset_pk_sequence!(‘table_name’)

I have not tried it on any other database.


   May 17

Delete a file permanently from Git history

Git has very sharp memory. It remember all its commits through out the life cycle of a project.

If you have accidentally pushed a file to Git and wanted to get rid of it from all the tags, branches and commit history, then try following:

1. git filter-branch -f –index-filter ‘git rm –cached –ignore-unmatch FILENAME’ –prune-empty — –all

command will run entire history of repo and all its tags, branches and remove the specified file.

2. git push origin master –force

a normal “git push” will fail.. so use –force to push your changes to remote.

[Reference: http://help.github.com/remove-sensitive-data/]


   May 11

Save time with bash aliases

While working on Rails development, I have been using console quite a lot. One thing which I find very handy are aliases.

A few key strokes are better than typing a long command. Following are the steps I followed to set aliases in bash:

1. vi ~/.bash_profile and add:

if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi

2. Setup your aliases in bash_aliases file:

vi ~/.bash_aliases

Thats all you need. A few sample aliases I have been using for a while are:

1. alias ar=”touch tmp/restart.txt” to restart rails app running under Pow or Passenger.

2. alias sc=”./script/console” to start Rails console in  2.3X apps.

3. alias rc=”./script/rails c” to start Rails console for Rails 3.X apps.

And dont forget to restart your terminal after adding an alias. I hope these few lines helps someone to speed up some development.

Best


   Apr 18

Facebook OAuthException Error validating verification code

While implementing FB connect for one of my recent project, I ran into an OAuthException. “Error validating verification code.”

My app settings were valid, so were FB app settings. It took me a while to find out that it was redirect_uri error.

If your Facebook app has App URI as:

http://foo.local

and your web application has: http://foo.local/

It will throw this exception. It took me around 30 minutes or so to resolve this error but time well spent/wasted. Updated my local app to http://foo.local/ and got oauth_token back from FB.

Thanks Facebook & StackOverflow.

 


   Oct 21

setup a cron job to run rake task

Have you ever find a need to setup a cron job to run a rake task for your Rails app? Well I have recently implemented a job to run a rake task on daily basis.

Here are the steps I followed:

$ sudo crontab -e

14 3 * * * cd /path/to/rails/app && /usr/local/bin/rake RAILS_ENV=production

 

What does this means? It means, every morning at 3:14 AM cd to my Rails app and run specified rake task using production environment.

Crontab file
Crontab syntax : A crontab file has five fields for specifying day , date and time followed by the command to be run at that interval.

*     *     *   *    *        command to be executed
-     -     -   -    -
|     |     |   |    |
|     |     |   |    +----- day of week (0 - 6) (Sunday=0)
|     |     |   +------- month (1 - 12)
|     |     +--------- day of        month (1 - 31)
|     +----------- hour (0 - 23)
+------------- min (0 - 59)

 

Hope it will help someone.

Happy Coding!


   Oct 06

Intercept and Redirect emails in Development mode with ActionMailer and Rails3

Have you ever run into an issue where you are testing email  functionality, especially for newly registered users where the system should send a confirmation email. The problem comes when you run out of email addresses while testing. You have already used your company’s email address, your personal email ids and your friends emails and there is still more testing to be done!!

Well how about you use any valid formatted email address in form field e.g. abc@testapp.com or abc1@testapp.com and all these get delivered to your company email address or your personal email address.

Rails3 and ActionMailer provides an interceptor functionality which will intercept any outgoing email and forward it to a specified email.

Following are the steps to setup an interceptor:

create lib/mail_interceptor.rb

#lib/mail_interceptor.rb

class DevelopmentMailInterceptor
  def self.delivering_email(message)
    message.subject = "[#{message.to}] #{message.subject}"
    message.to = "wilmar.test@gmail.com"
    message.content_type = "text/html"
  end
end

by default it sends plain text emails, if you want to send HTML formatted emails then add following right after message.to

message.content_type = "text/html"

Next

create config/initializers/setup_mail_interceptor.rb

require 'lib/development_mail_interceptor'
ActionMailer::Base.register_interceptor(MailInterceptor) if Rails.env.development?

 

And let the magic begins. It will intercept any outgoing email and send it to the email address specified in mail_interceptor.

Happy Testing and Coding


   Oct 06

Preview emails in browser without sending using Rails3

Recently in a project, I found a need to view layout for the emails which I will be sending to users. The usual way is fill the form and get confirmation email. But it is a tedious process. This registration form is pretty long, so designers have to fix layout, css and then refill the form and get confirmation email and fix it again.

Means a lot of work. So I started looking for a solution to preview my email without sending or filling the whole form and I found a great idea posted by 37Signals i.e. mail_view gem.

Setting mail_view gem was easy and it worked like a charm. Developers are happy and I am happy.

Following are the steps I used to setup mail_view:
FYI: I am using Rails 3.0.X

# config/routes.rb

  if Rails.env.development?
    mount UserMailer::Preview => 'mail_view'
  end
#user_mailer.rb
class UserMailer < ActionMailer::Base
  default :from => "from@example.com"
  def signup_nofitication(user)
    @user = user
  end

  class Preview < MailView
    # Pull data from existing fixtures
    def signup_nofitication
      user = User.first

       UserMailer.signup_nofitication(user)
    end
  end

end
# app/views/user_mailer.signup_notification.text.html.erb
<h3>Hello <%= @user.name %></h3>

<p>Your email is
  <span> <%=@user.email%></span>
</p>

 

Open your browser and goto http://yoursite.local/mail_view. It will list all the methods you have in your Preview class. In my case it was only “signup_notification”. Click on it and it will render your email template.

Now I dont have to fill all that form, send email. Designers can fix CSS and layout and view changes right in the browser. It made cross browser email testing a lot easier.

Thanks to 37Signals.

Happy Coding


   Sep 28

How to use Chrome with Capybara

By default Cucumber and Capybara uses Firefox as default test browser. But if you ever find a need to use Chrome as your test browser then add following to your:

 

$spec_helper.rb

Capybara.register_driver :selenium_chrome do |app|
  Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
if Selenium::WebDriver::Platform.find_binary “chromedriver”
  Capybara.default_driver = :selenium_chrome
else
  Capybara.default_driver = :selenium
end
Thanks to Josh Owens (@joshowens) to share it: https://gist.github.com/1248999
Happy Testing.

   Jul 13

Rails nested form with checkbox list

While creating a checkbox list for a nested form, I always forget syntax for it. So thought to write a post, so that I can use it as a reference in future and maybe it can help someone.

I have a User and Language model. User can have many languages and Language can have many users. I wanted a feature where I should be able to assign multiple languages to a specific user on a give screen. So I followed following method:

model user.rb

class User < ActiveRecord::Base
has_many :user_languages
has_many :languages, :though => :user_languages
end

model language.rb

class Language < ActiveRecord::Base
has_many :user_languages
has_many :users, :though => :user_languages
end

and I have one junction table language_users, which looks like following:


create_table "language_users", :force => true do |t|
t.integer "language_id"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
end

So far it is all simple. Now I needed a form where I will display all available languages and languages opted by the selected user. Following is the view:


= form_for @user, :url => admin_user_path(@user) do |f|
%ul
- @languages.each do |language|

%li
= check_box_tag "user[language_ids][]", campaign.id, @user.languages.include?(language)
= language.name
= submit_tag "Update"

pretty straight forward huh. I have a form_for a selected user. Looping through all available languages and marking checked if user has opted for a languages. If I want to assign/removed a language to this user, I will check/uncheck a checkbox and update.

Update method looks like following:


params[:user][:language_ids] ||= []
user = User.find params[:id]
user.update_attributes(params[:user])

and I am done here. It will do all the magic for me.

Happy Coding.