Browsed by
Category: English

How to run your feature specs using Capybara and Headless Chrome

How to run your feature specs using Capybara and Headless Chrome

Google has recently announced a way to run the Chrome browser in a headless environment. If you’re using Capybara gem, you can easily start using headless Chrome. Without further ado, let’s do it:

1) Make sure you have one of the following Chrome versions:

  • 57+ on Linux
  • 59+ on macOS
  • 60+ on Windows

(the last one hasn’t been released yet, so you have to use the beta, aka “Canary”)

2) Add (or update) the gem selenium-webdriver;

3) Make sure you’re using ChromeDriver version 2.30 or higher. You can install it by running brew install chromedriver on macOS or apt-get install chromium-chromedriver on Debian/Ubuntu Linux.

4) Add the following driver to your spec_helper.rb or rails_helper.rb:

Capybara.register_driver :chrome do |app|
  Capybara::Selenium::Driver.new app, browser: :chrome,
    options: Selenium::WebDriver::Chrome::Options.new(args: %w[headless disable-gpu])
end

Capybara.javascript_driver = :chrome

Done, enjoy headless Chrome! ᕕ( ᐛ )ᕗ


You might get a warning like the following:

WARN Selenium [DEPRECATION] :args or :switches is deprecated. Use Selenium::WebDriver::Chrome::Options#add_argument instead.

Make sure you don’t have another registered driver, I made this mistake myself and had an iphone driver, which was passing args in the old way and turned out to be the reason why I was getting the warning.

How to setup multiple Heroku accounts (in heroku-cli)

How to setup multiple Heroku accounts (in heroku-cli)

Both Heroku and its CLI are great. However, there’s no way to access multiple accounts via terminal out of the box. If you have a personal and a work account and need an easy way to switch between them, I have good news for you! :-)

Heroku’s team has created a plugin called heroku-accounts. You can find how to install and how to use in its project page on Github.

To make it even easier, I’ve added the following aliases to my ~/.zshrc (or ~/.bashrc):

# Heroku
alias hp='heroku accounts:set personal'
alias hw='heroku accounts:set work'

Happy hacking!

[Ruby] How to get the name of the calling method?

[Ruby] How to get the name of the calling method?

I was about to run a rake task which would make important changes in my database.

My code was similar to this:

def migrate_active_accounts
  accounts = Account.active
  # Code to migrate accounts here...
end

def migrate_inactive_accounts
  accounts = Account.inactive
  # Code to migrate accounts here...
end

This migration was very critical. Thus, I decided to log everything to make sure it would run as expected. So I wrote a separate method to log what accounts were going to run by which method. In order to do that, I’d need to know which method was calling my logger method. I ended up finding the answer on StackOverflow (where else I would? :p).

Solution

As usual, Ruby has a neat solution for it: Kernel module has a caller_locations method, which returns an array with the current execution stack. So all we need to do is to use caller_locations.first.label to get the first element from the stack and then get its label.

My final code was looking like the following:

def migrate_active_accounts
  accounts = Account.active
  log_migration_info(accounts)
  # Code to migrate accounts here...
end

def migrate_inactive_accounts
  accounts = Account.inactive
  log_migration_info(accounts)
  # Code to migrate accounts here...
end

private

def log_migration_info(accounts)
  caller_method = caller_locations.first.label

  Rails.logger.info "Running [MyClass##{caller_method}]
    for the following accounts: #{accounts.map(&:id).to_sentence}"
end

Ruby prior to 2.0

If you’re using an old version of Ruby (even though you shouldn’t), you’ll need to use caller method along with a regular expression:

caller.first[/`(.*)'/, 1]

Happy hacking!

Prevent Rails from writing development/test log files

Prevent Rails from writing development/test log files

I can’t remember the last time I needed to open/read log/development.log or log/test.log. This is just consuming disk space unnecessarily (my test.log easily reaches more than 1 GB!). After talking to some other developers, all of them agreed they don’t use it as well.

So what I’ve been doing in my projects is adding the following code. Note that it’ll still display the logs through the STDOUT though.

Rails 4 or higher

# config/environments/development.rb

# Prevents from writing logs on `log/development.log`
logger           = ActiveSupport::Logger.new(STDOUT)
logger.formatter = config.log_formatter
config.logger    = ActiveSupport::TaggedLogging.new(logger)
# config/environments/test.rb

# Prevents from writing logs on `log/test.log`
config.log_level = :warn
logger           = ActiveSupport::Logger.new(STDOUT)
logger.formatter = config.log_formatter
config.logger    = ActiveSupport::TaggedLogging.new(logger)

Rails 3

# config/environments/development.rb

# Prevents from writing logs on `log/development.log`
logger        = ::Logger.new(STDOUT)
config.logger = ActiveSupport::TaggedLogging.new(logger)

# Replace `config.active_support.deprecation = :log` with:
config.active_support.deprecation = :stderr
# config/environments/test.rb

# Prevents from writing logs on `log/test.log`
config.log_level = :warn
logger           = ::Logger.new(STDOUT)
config.logger    = ActiveSupport::TaggedLogging.new(logger)

Ps.: I’ve sent a suggestion to rubyonrails-core mailing list to make it default, let’s see their thoughts.

Puma vs. Unicorn

Puma vs. Unicorn

TL; DR – You should start using Puma.

Rails has switched the default server from Webrick to Puma in Rails 5!

It also supports Action Cable (one of the new features from Rails 5) and Basecamp said they’re using Puma in production.

I was wondering if Puma has been in fact better than Unicorn so I’ve read some blog posts about it:

Basically, the answer is yes – it is a bit better, but don’t wait for a huge improvement. I’d say it might be a good idea if you’re:

  • about to start a new project;
  • about to migrate your current project to Rails 5;
  • unhappy with your Rails 3 / 4 app server performance.
Rake task to import a production DB dump

Rake task to import a production DB dump

Every now and then I need to write a script (rake task) to import a production database dump.

This is code I usually use:

require 'yaml'

namespace :db do
  desc 'Downloads and imports a production DB dump'
  task :import_production_dump do
    puts '➙ Generating production DB dump...'

    execute_on_server %(
      PGPASSWORD="`cat /var/www/project/current/config/database.yml | \
        grep password | awk '{ print $2 }'`" \
        pg_dump database_name -h custom_url.rds.amazonaws.com -U user_name \
        --column-inserts --no-owner --no-privileges > backup.sql
    )

    puts '➙ Downloading production DB dump...'
    system "scp #{server_user_and_host}:#{backup_file_name} ."

    puts '➙ Deleting production DB dump...'
    execute_on_server 'rm backup.sql'

    puts '➙ Cleaning your local DB...'
    %w(drop create).each { |task| Rake::Task["db:#{task}"].invoke }

    puts '➙ Importing production DB dump...'
    system "bin/rails db development < #{backup_file_name} > /dev/null"

    puts '➙ Removing local dump...'
    system "rm #{backup_file_name}"

    puts '➙ Done!'
  end

  def execute_on_server(commands)
    system %(ssh -T #{server_user_and_host} << 'SSH'
      #{commands}
    SSH).split("\n").map(&:strip).join("\n")
  end

  def server_user_and_host
    'username@example.com'
  end

  def backup_file_name
    'backup.sql'
  end
end

Let me know in the comments if you have a better solution! Perhaps a tiny gem? ツ

Why I regenerated my SSH key and maybe you should too

Why I regenerated my SSH key and maybe you should too

security

I think we all agree it’s a good practice to regenerate your SSH key from time to time. Not sure about you, but the first thing that comes to my mind when I think about that is: it’d take forever to replace my key in all servers I need to access, all online services that use my key, etc.

Overcoming my laziness, I decided at least to list every place I’d have to update it. Interesting fact: it turned out that it was pretty much a small list:

  • Servers
  • Github
  • BitBucket
    • Although now it looks more reasonable, I was still lazy to do it. Then, a few days ago, I noticed that Github recommends the use of HTTPS instead of SSH for Git repositories syncs:

      Github - HTTPS vs SSH

      What does one thing have to do with another? Well, by using HTTPS, you don’t need to upload your SSH key to Github (check this out: mine isn’t longer at Github). BitBucket also supports it, which means I’d be able to regenerate my SSH key without having to upload it again to these services.

      Servers

      What’s left? Servers! From now on, every time I realise it’s time to regenerate my SSH key, all I need to update are the servers. I ended up making a list of servers that I’d need to update and found out in the end it wasn’t a big list and it’d be way easier than I thought it would.

      Let’s face the truth: I had been using the same SSH key in the last 5 years or so and it’d be totally worth it to ensure my security as well as the security of the projects from the company I work for.

      Becoming safer

      There’s more! This is the interesting part of this post: I’ve changed other things that made everything even safer:

      1. My new SSH key uses 4096 bitsrecommended by Github – instead of the default (2048 bits).
      2. As I mentioned before, I’ve changed all my local repositories to use HTTPS instead of SSH (see how in the end of this post).
      3. I’m now using a personal access token rather than my Github password (you can create it here), along with two-factor authentication, which I was already using.
      4. Cool, but would I need to type this token every time? Nope. There’s a nifty tool called ssh-agent that can save your token. If you’re using OS X, it’s even easier: Keychain can save and encrypt your token for you.
      5. My SSH key now has a passphrase, also saved encrypted in OS X’s Keychain, which means I don’t need to type it every time either.

      HTTPS is faster!

      According to some tests I made here, HTTPS is faster than SSH:

      # SSH
      $ time git clone git@github.com:rails/rails.git
      # 24.28s user 9.56s system 49% cpu 1:08.20 total
      
      # HTTPS
      $ time git clone https://github.com/rails/rails.git
      # 13.52s user 6.41s system 39% cpu 50.730 total
      

      In order to use HTTPS in my Git repos, do I need to re-clone every project?

      Nope. Just edit the file .git/config (within your project folder) and replace:

      url = git@github.com:username/repo.git

      with:

      url = https://github.com/username/repo.git

      Conclusion

      Regenerating your SSH key every now and then isn’t painful as you think it is. I’d recommend doing it every 3 years or even less if you’re paranoic or you work on something critic.

What is “frozen_string_literal” in Ruby?

What is “frozen_string_literal” in Ruby?

ruby3

Freezing Strings feature improves apps performance by freezing Strings. So, Matz – Ruby’s creator – decided to make all String literals frozen (immutable) by default in Ruby 3.0.

In order to have a transition path to this coming big change, it was decided to have a magic comment at the beginning of files, so you can use in Ruby 2.x.

To do so, just add this comment in the first line of your files:

# frozen_string_literal: true

class YourClass
  # ...
end

Try adding it to your spec_helper or rails_helper file and let me know in the comments if your performance has improved!

More info: Ruby issue #8976.

If you really need to create a monkey patch, do it properly

If you really need to create a monkey patch, do it properly

Ruby

Sometimes we need to create a monkey patch for a gem or external lib. In these cases, it’s good to force it to fail if the gem has been bumped up. Let’s use Paperclip as an example:

if Paperclip::VERSION != '1.2.3'
  # If you see this message, please test removing this file
  # If it's still required, please bump up the version above
  fail 'Please remove me, Paperclip version has changed'
end

If the gem doesn’t provide you the version through a method, you can solve it with:

if Bundler.load.specs.find { |gem| gem.name == 'paperclip' }.version.to_s != '1.2.3'
  # If you see this message, please test removing this file
  # If it's still required, please bump up the version above
  fail 'Please remove me, Paperclip version has changed'
end

Or even when you’re waiting for a new Rails version, e.g.:

fail 'Remove this file' if Rails::VERSION::MAJOR >= 5
Measuring and improving your Rails app quality

Measuring and improving your Rails app quality

I’ve just written a blog post on the NetEngine’s blog:

http://netengine.com.au/blog/measuring-and-improving-your-rails-app-quality/

I hope you enjoy it.

CampJS 2014 – the best geek event I ever attended

CampJS 2014 – the best geek event I ever attended

A few days ago I was in CampJS, the best geek event I ever attended.

campjs

This is the official website (which is pretty nice by the way): http://campjs.com/.

Why it was the best in my opinion:

  • It happened in an amazing place – to be near of the nature, changing the usual environment is renewable. I definitely recommend to try it.
  • I had the chance to talk to a lot of other Javascript developers
  • Awesome talks and workshops
  • Good food and beers
  • A live podcast was recorded in there

A friend of mine (@erikEcoologic) have written an awesome blog post about the event, so go check it out! ;)

A special thanks to @brucestronge and to NetEngine for the tickets!

Video & some pictures

IMG_0

IMG_1067

IMG_1099

IMG_1199

IMG_1202

IMG_1206

IMG_1267

How to use command line on Mac OS X

How to use command line on Mac OS X

A friend of mine (who came from Windows world) have bought a Mac recently and he asked me how to use command line on Mac OS X:

My answer was:

1) 99% of commands are identical in Linux. This is good news as there are a lot of material about it available on the Internet;

2) Terminal.app from OS X is cool, but it’s not perfect. I (and 90% of developers I know) use iTerm2 (http://iterm2.com/). It’s light (3mb), free, open-source, has a better interface than the native one and it rocks! Best terminal I’ve ever used.

3) This is the most useful topic in my answer: an awesome cheat-sheet with command line commands made by the Git-tower team;

4) To finish: I’ve recorded a screencast showing up how to create scripts in OS X and Linux (similar to BAT file in Windows). Unfortunately this is only available in portuguese:

What do I have in the OS X’s menu bar?

What do I have in the OS X’s menu bar?

menubar

Application Description Type
Caffeine Prevent your Mac from automatically going to sleep, dimming the screen or starting screen savers Free
ColorSnapper Color picker Paid
1Password Password manager Paid
Dropbox File hosting service Free / Paid
CrashPlan Online data backup in real time Paid
Spectacle Window control

Free / Open source
Evernote I love Evernote, but I don’t use this icon for anything.
When I close it, it returns automatically ¯\_(ツ)_/¯
Free / Paid
Chrome notifications I never really use it, but I guess there’s no way to remove it though Free
Text Expander Custom keyboard shortcuts into frequently-used texts Paid
AirPlay Play content on your TV via Apple TV Free
Time Machine Built-in backup feature of OS X that works with an external HD or Time Capsule Free
An awesome Wiki built with Ruby and Rails!

An awesome Wiki built with Ruby and Rails!

I’ve been worked on a small (but awesome) open-source project.

I’m talking about ruby_wiki – a simple wiki built with Ruby on Rails:
https://github.com/lucascaton/ruby_wiki

As I said before – it’s quite simple, although it works fine.
Anyway, would be nice to have more features in this project, so, if you’re a developer and have any interest in that, feel free to fork the project and contribute.

Some screenshots:


1


2


3


4


5


6

Have a Rails 2 app? You can run it on the newest Ruby!

Have a Rails 2 app? You can run it on the newest Ruby!

old_rails_with_new_ruby

Do you have a legacy Rails application which is still running on Rails 2?

There are several reasons to migrate your application to new Rails versions, like to improve the security, to be able to use a better syntax, to take advantage of new features and also because most of current gems will only work on Rails 3 or higher. However, sometimes it’s hard to do that, especially for big projects. And certainly today there’re many project still running on Rails 2.

But there’s one good thing you can (and should) do! I’m talking about to use the newest Ruby version. Yes, I’m serious. When I wrote this post, the current Ruby version was 2.1.1 – and it’s not so hard to get it working fine with Rails 2.

Obviously, would be better if you have a good test coverage.

That said, let’s do it in a few steps:

Replacements

1. Gemfile

Rails 2 apps don’t use Bundler by default, so if you don’t have Bundler managing your gems yet, you should check here how to do that.

# There's no way to ensure that the next Ruby versions will work,
# but so far the current one works fine:
ruby '2.1.1'

# The same for rake:
rake '10.1.1'

# You might need the iconv gem:
gem 'iconv'

2. Rakefile

# Replace:
# require 'rake/rdoctask'

# with:
require 'rake/task'

3. config.ru

# Replace:
# require 'config/environment'

# with:
require File.dirname(__FILE__) + '/config/environment'

4. FasterCSV => CSV

Replace all FasterCSV constant with CSV. Also, include require 'csv' to relevant files (or include this require to config/environment.rb).

Inclusions

5. config/environment.rb

# Include this before the `Rails::Initializer.run` line:
if RUBY_VERSION >= '2.0.0'
  module Gem
    def self.source_index
      sources
    end

    def self.cache
      sources
    end

    SourceIndex = Specification

    class SourceList
      # If you want vendor gems, this is where to start writing code.
      def search(*args); []; end
      def each(&block); end
      include Enumerable
    end
  end
end

6. config/initializers/paperclip.rb

# The patches below are needed when using an old version of PaperClip + Ruby 2.x
# https://github.com/thoughtbot/paperclip/issues/262
# https://github.com/thoughtbot/paperclip/commit/1bcfc14388d0651c5fc70ab9ca3511144c698903

module Paperclip
  class Tempfile < ::Tempfile
    def make_tmpname(basename, n)
      extension = File.extname(basename)
      sprintf('%s,%d,%d%s', File.basename(basename, extension), $$, n.to_i, extension)
    end
  end
end

module IOStream
  def to_tempfile
    name = respond_to?(:original_filename) ? original_filename : (respond_to?(:path) ? path : 'stream')
    tempfile = Tempfile.new(['stream', File.extname(name)])
    tempfile.binmode
    self.stream_to(tempfile)
  end
end

New files

7. config/initializers/ruby2.rb

# This is a very important monkey patch to make Rails 2.3.18 to work with Ruby 2+
# If you're thinking to remove it, really, don't, unless you know what you're doing.

if Rails::VERSION::MAJOR == 2 && RUBY_VERSION >= '2.0.0'
  module ActiveRecord
    module Associations
      class AssociationProxy
        def send(method, *args)
          if proxy_respond_to?(method, true)
            super
          else
            load_target
            @target.send(method, *args)
          end
        end
      end
    end
  end
end

8. config/initializers/rails_generators.rb

It'll prevent Rails migration generator from stop working, otherwise you'll receive the following error message:

undefined local variable or method `vars' for # Rails::Generator::Commands::Create

(Thanks to Mr. S and jnwheeler44 for helping me to fix this one)

# This is a very important monkey patch to make Rails 2.3.18 to work with Ruby 2+
# If you're thinking to remove it, really, don't, unless you know what you're doing.

if Rails::VERSION::MAJOR == 2 && RUBY_VERSION >= '2.0.0'
  require 'rails_generator'
  require 'rails_generator/scripts/generate'

  Rails::Generator::Commands::Create.class_eval do
    def template(relative_source, relative_destination, template_options = {})
      file(relative_source, relative_destination, template_options) do |file|
        # Evaluate any assignments in a temporary, throwaway binding
        vars = template_options[:assigns] || {}
        b = template_options[:binding] || binding
        # this no longer works, eval throws "undefined local variable or method `vars'"
        # vars.each { |k, v| eval "#{k} = vars[:#{k}] || vars['#{k}']", b }
        vars.each { |k, v| b.local_variable_set(:"#{k}", v) }

        # Render the source file with the temporary binding
        ERB.new(file.read, nil, '-').result(b)
      end
    end
  end
end

RSpec

9. Make sure you're using the last compatible version with Rails 2.3.18:

gem 'rspec', '1.3.2'
gem 'rspec-rails', '1.3.4'

10. Remove the file script/spec.

11. lib/tasks/rspec.rake

Remove all the following lines:

gem 'test-unit', '1.2.3' if RUBY_VERSION.to_f >= 1.9
rspec_gem_dir = nil

Dir["#{Rails.root}/vendor/gems/*"].each do |subdir|
  rspec_gem_dir = subdir if subdir.gsub("#{Rails.root}/vendor/gems/","") =~ /^(\w+-)?rspec-(\d+)/ && File.exist?("#{subdir}/lib/spec/rake/spectask.rb")
end

rspec_plugin_dir = File.expand_path(File.dirname(__FILE__) + '/../../vendor/plugins/rspec')

if rspec_gem_dir && (test ?d, rspec_plugin_dir)
  raise "\n#{'*'*50}\nYou have rspec installed in both vendor/gems and vendor/plugins\nPlease pick one and dispose of the other.\n#{'*'*50}\n\n"
end

if rspec_gem_dir
  $LOAD_PATH.unshift("#{rspec_gem_dir}/lib")
elsif File.exist?(rspec_plugin_dir)
  $LOAD_PATH.unshift("#{rspec_plugin_dir}/lib")
end

Ruby syntax

12. Some details has been changed in Ruby syntax, especially from 1.8.x to 1.9.x.

Example 1:

# Replace:
when 'foo': bar

# with:
when 'foo' then bar

Example 2:

The behaviour for protected methods in new Ruby versions is a little bit different. See more in this post.

# In some cases, you might need to replace:
respond_to?(:foobar)

# with:
respond_to?(:foobar, true)

Example 3 (Yaml files):

# Replace:
order: [ :day, :month, :year ]

# with:
order:
  - :year
  - :month
  - :day

Ruby changes

13. The default encoding for Ruby 2.0 (or higher) is UTF-8. So, remove all the code similar to:

# encoding: utf-8

Or:

$KCODE = 'UTF-8'

Important note (included on July 27, 2014)

Check the comments below: Gabriel Sobrinho, Kyle Ries and Greg made some useful comments.

Conclusion

Each project could have different issues, but I hope this little guide helps you to use new Ruby versions in legacy Rails applications!

How to improve your software development team’s communication

How to improve your software development team’s communication

I’ve just written another post on the NetEngine’s blog:

http://netengine.com.au/blog/how-to-improve-your-software-development-team-s-communication/

I hope you enjoy it.

Agile methodologies for software development

Agile methodologies for software development

Yesterday, I wrote my first blog post on the NetEngine blog:

http://netengine.com.au/blog/agile_methodologies_for_software_development/

I hope you enjoy it.

Interesting script written in Ruby: “The Globe”

Interesting script written in Ruby: “The Globe”

Minutes ago I received this link from some friends. It’s very interesting (and crazy).

Create an empty ruby file, paste this content and save as a.rb.

v=0000;eval$s=%q~d=%!^Lcf<LK8,                  _@7gj*LJ=c5nM)Tp1g0%Xv.,S[<>YoP
4ZojjV)O>qIH1/n[|2yE[>:ieC       "%.#%  :::##"       97N-A&Kj_K_><wS5rtWk@*a+Y5
yH?b[F^e7C/56j|pmRe+:)B     "##%      ::##########"     O98(Zh)'Iof*nm.,$C5Nyt=
PPu01Avw^<IiQ=5$'D-y?    "##:         ###############"    g6`YT+qLw9k^ch|K'),tc
6ygIL8xI#LNz3v}T=4W    "#            #.   .####:#######"    lL27FZ0ij)7TQCI)P7u
}RT5-iJbbG5P-DHB<.   "              ##### # :############"   R,YvZ_rnv6ky-G+4U'
$*are@b4U351Q-ug5   "              #######################"   00x8RR%`Om7VDp4M5
PFixrPvl&<p[]1IJ   "              ############:####  %#####"   EGgDt8Lm#;bc4zS^
y]0`_PstfUxOC(q   "              .#############:##%   .##  ."   /,}.YOIFj(k&q_V
zcaAi?]^lCVYp!;  " %%            .################.     #.   "  ;s="v=%04o;ev"%
(;v=(v-($*+[45,  ":####:          :##############%       :   "  ])[n=0].to_i;)%
360)+"al$s=%q#{  "%######.              #########            "  ;;"%c"%126+$s<<
126}";d.gsub!(/  "##########.           #######%             "  |\s|".*"/,"");;
require"zlib"||  "###########           :######.             "  ;d=d.unpack"C*"
d.map{|c|n=(n||  ":#########:           .######: .           "  )*90+(c-2)%91};
e=["%x"%n].pack   " :#######%           :###### #:          "   &&"H*";e=Zlib::
Inflate.inflate(   "  ######%           .####% ::          "   &&e).unpack("b*"
)[0];22.times{|y|   "  ####%             %###             "   ;w=(Math.sqrt(1-(
(y*2.0-21)/22)**(;   " .###:             .#%             "   ;2))*23).floor;(w*
2-1).times{|x|u=(e+    " %##                           "    )[y*z=360,z]*2;u=u[
90*x/w+v+90,90/w];s[(    " #.                        "    ;y*80)+120-w+x]=(""<<
32<<".:%#")[4*u.count((     " .                   "     ;"0"))/u.size]}};;puts\
s+";_ The Qlobe#{" "*18+ (       "#  :#######"       ;"Copyright(C).Yusuke End\
oh, 2010")}";exit~;_ The Qlobe                  Copyright(C).Yusuke Endoh, 2010

After that, just run this script using:

while true; do clear; ruby a.rb | tee b.rb; sleep 0.2; mv -f b.rb a.rb; done
Hellо, I am a compiler

Hellо, I am a compiler

robot

I copied this little text from a comment on the Stackoverflow website. I really enjoyed it ;)

Hellо, I am a compiler.
I just scanned thousands of lines of code while you were reading this sentence. I browsed through millions of possibilities of optimizing a single line of yours using hundreds of different optimization techniques based on a vast amount of academic research that you would spend years getting at. I won’t feel any embarrassment, not even a slight ick, when I convert a three-line loop to thousands of instructions just to make it faster. I have no shame to go to great lengths of optimization or to do the dirtiest tricks. And if you don’t want me to, maybe for a day or two, I’ll behave and do it the way you like. I can transform the methods I’m using whenever you want, without even changing a single line of your code. I can even show you how your code would look in assembly, on different processor architectures and different operating systems and in different assembly conventions if you’d like. Yes, all in seconds. Because, you know, I can; and you know, you can’t.

P.S. Oh, by the way you weren’t using half of the code you wrote. I did you a favor and threw it away.

Getting root permissions on a file inside of Vim

Getting root permissions on a file inside of Vim

Sometimes you open a file that you need root permissions to save it.
When it happen, you can close and reopen the Vim (with sudo) or you also can do:

:w !sudo tee %

Thanks to @dlisboa for the tip.

A simple way to deploy your Rails applications

A simple way to deploy your Rails applications

Sometimes I prefer to use a simpler way to deploy my Rails applications instead of install and configure some complex tool (eg.: capistrano).

A very simple way to do this is creating a shell script within the /script directory, which will access the server via SHH:

#! /bin/bash
# script/deploy.sh

TAG=deployed_at_$(date +"%F_%H-%M")
git tag -m '' -a $TAG
git push --tags

ssh user@your_domain.com << 'SSH'
  cd /var/rails_apps/my_app
  rm -rf public/assets
  git pull
  bundle install --without development test
  bundle exec rake db:migrate db:seed assets:clean assets:precompile
  touch tmp/restart.txt
  git describe > public/version
SSH

After that, a tag will be created in the git repository. Now, you know exactly the date and time when it was deployed.

And you can find out which version (tag from git) is in production accessing the URL your_domain.com/version.

your_domain

Update on March 8, 2013:

I’ve created another script which accepts the -q param (quick).
https://gist.github.com/lucascaton/5118852

How to test ElasticSearch in a Rails application

How to test ElasticSearch in a Rails application

Since I started using ElasticSearch in my Rails applications, I had a problem to create separate indexes for the automated tests.

The problem is: there is no way to create more than one database in ElasticSearch. You can create different indexes, but no different databases. But creating indexes with different names doesn’t solve the problem: it’s necessary to configure our Rails models in order to work with a different index name when the tests is running.

I’m using the tire and RSpec gems and in this post, I’ll explain how to separate indexes for development and test environments.

First of all, I’ve included the code below in file config/initializers/tire.rb:

if Rails.env.test?
  prefix = "#{Rails.application.class.parent_name.downcase}_#{Rails.env.to_s.downcase}_"
  Tire::Model::Search.index_prefix(prefix)
end

And I set manually the index name in the model (assuming that there is a Movie model):

index_name "#{Tire::Model::Search.index_prefix}movies"

Done! After that, when your application is running in development environment, the name of indexes will be “movies”. But if it’s in the test environment, the name of indexes will be “appname_test_movies” and then the tire gem and your models can perform the search with different indexes!

Deleting test indexes

In order to delete the test indexes after the suite has finished running, just add the following code to file spec/integration_helper.rb (or similar):

RSpec.configure do |config|
  config.after(:all, type: :request) { delete_movie_index }
end

And create a custom macro, which will delete the indexes:

def delete_movie_index
  Movie.index.delete
end

Demo app

I created a small application to demonstrate the technique explained in this post:
https://github.com/lucascaton/elasticsearch_app_example

I hope this has been helpful!