Category Archives: rails

Rendering Rails Template as String

Hello,

This is a nice trick that is useful, for example if you need to send an html string via an api endpoint.
Instead of constructing the string manually like this:

# api controller
@title = "some title"
@html_string ="<h1>[email protected]}</h1>"

You can put the template into a template file, for example ‘html_string.erb’, and call ‘render_to_string’

# html_string.erb
<h1><%= @title %></h1>
# api controller
@html_string = render_to_string(:html_string)

This is especially useful if the html string is dynamic and complicated, as you can use partials.

Loading Gem from Local Source

As a ruby programmer, we are treated with a rich ecosystem of library called the ruby gems.

Along the way, sometime you found a new need that can’t be fulfilled by your current gem choice. This happened to me last month with geocoder.

When this happens you have two choices:
1. Roll out your own solution from scratch
2. Patch the current gem so that it can solve your problem

From my case, I need to use Googe Places Search API for geocoding, that the geocoder didn’t support yet. I check that it is not difficult to patch the gem (not always the case) and my code base already uses the gem a lot, so I decided to patch the gem.

It might be confusing if this is the first time you want to patch a gem. How to do edit the files locally? Turns out it is quite easy.
First, fork the gem repository, and clone the fork to your local computer, for example to:

 ~/gempatch/geocoder 

Then modify your project Gemfile to specify your local path:

# Gemfile
 
gem 'geocoder', path: '~/gempatch/geocoder'

Run bundle and voila! your project is running the gem from local source. Any modification you made on the gem locally will be immediately reflected on your project. Once you are happy with your modification, save and commit your change, and push it to the gem fork on your repository.

Now you can set your project to use the gem from your repository, so it will work in production

# Gemfile
 
gem 'geocoder', git: "git://github.com/waruboy/geocoder.git", branch: "place-search"

Oh, and please consider to create a Pull Request to the main repository of the gem. It’s a nice way to contribute to the community and also great to put your name out there. Just make sure to read if the gem have any contributing guidelines before doing so.

Happy patching!

PS. Thanks a lot for Tyler Tringas from Storemapper for sponsoring my contribution work to the Geocoder gem.

Faster and Lighter with pluck_to_hash Gem

Rails Active Record is very convenient. It has many utilities that makes dealing with data and persistence a breeze. Without AR, I don’t think I will stick with Rails.

However, as it goes, there’s no free lunch. Active Record objects are big and heavy. Often this is an acceptable trade off. However, when you need to process a lot of record and intend to just read the attributes values, AR might be too heavy and unnecessary.

When you only need values of some fields from a record, you can use AR’s `pluck`
For example you need the name and address of a user

User.where(id: 7).pluck(:name, :location).first
#
# ["John Shepard", "Normandy"]

This will retrieve the requested values without instantiating AR object, which save you both time and memory.

However, if you need to retrieve a lot of values from a collection of records, processing the arrays of values can become unwieldy. An example of this case is if you are building an “index” endpoint of an api with thousands of records per request. This is a real case that I have to do in one of my project.

For this, there is a handy gem that is called “pluck_to_hash”.
https://github.com/girishso/pluck_to_hash
No points for guessing it’s function. Basically it extends AR so you can do this:

User.limit(2).pluck_to_hash(:name, :location)
#
# [{:name=>"John Shepard", :location=>"Normandy"}, {:name=>"Urdnot Wrex", :location=>"Tuchanka"}]

Nice right?

Also, if you happens to use RABL for JSON templating, worry not, the gem also got you covered. RABL needs the record attributes to be accessible from a dot notation. This gem also supply `pluck_to_struct`, which looks like this

User.limit(2).pluck_to_struct(:name, :location)
#
# [#<struct name="John Shepard", location="Normandy"> #<struct name="Urdnot Wrex", location="Tuchanka">]

On one case, converting AR object to struct gave me ~3x faster response, while drastically reduce the memory usage. Unfortunately I don’t monitor exactly how much the memory saving from that particular endpoint, but the app server memory usage is reduced by 40%, so it should be more than that.

So, if you only need to read from some records and looking for more performance, this approach offer you some low hanging fruits.

Checking Idle Transaction on Heroku’s Postgresql

If you ever have connection problem with your postgresql instance on heroku, this post might help you.

One time one of my resque workers is dead when running long query (deleteing ~80k rows in a table). After that I got┬átons of timeout errors from my app. I even can’t do DELETE and UPDATE from one-off dyno

First, lets check all the process connected to your heroku postgresql instance

heroku pg:ps -a appname

you can see if there is some “idle in transaction” process. It’s likely the culprit. Take notes of the pid, then kill it with

heroku pg:kill pid_number -a appname

After you kill all those idle processes, your database should be free again.

Large CSV Import on Heroku

In the recent months, I’ve been lucky to work with Tyler Tringas, the founder of Storemapper.co. For your info, store mapper is a store locator snippet that you can put on your website and shopify page. We already have a lot of happy customer such as Beardbrand and Uber. If you are a business owner looking for a store locator solution, try it out!

One interesting that we solved recently is how to import a large CSV file on heroku. Tyler has documented it well in his blog post. If you have any question regarding that, feel free to comment here ­čÖé

Books: Agile Web Development with Rails 4

I just finished this book from The Pragmatic Bookshelf. Agile Web Development with Rails 4

agile web development with rails

The book is divided into three major part. The first part is an introductory part about ruby, how to install Rails, etc. The second part discussed about how to build an online catalog using Rails. You can check out the online catalog that I built from this book here. I wish the look is not so bland, but anyway it does what it is supposed to do. The last part discussed many Rails topics in-depth, such as Active Records, Rails dependencies, etc.

If you have finished your first introductory materials to Rails and looking for more learning materials, I can recommend this book for you.

Setting Environment Variable with Figaro Gem

When developing with Rails, often we have to include confidential information in our code. For example if we need to input our API key or some login information. If you are working on open source software or you share your repository with other people, you might want to remove this confidential information from your codes.

One method to secure the information is to move them to environment variables, and read the information variable from the code. Something like this

Pusher.key    = ENV["pusher_key"]

However, setting the environment variable manually might become annoyance if you have to do it many times.

Figaro gem to the rescue! With Figaro, you can just place all your variables in a file named config/application.yml, for example like this

pusher_key: "7381a978f7dd7fas2437"

The previous code will read the environment variable from the application.yml file. Of course you have to remove the application.yml from your repository.

You also can set environment specific variables using figaro. For example:

pusher_key: "7381a978f7dd7fas2437"
test:
  pusher_key: "ad612fh4a44dcac1fb28"

If you want to learn more about environment variable and rails, this article by Taylor Mock and Daniel Tahoe might be useful.

Rails 4.2 Launched with Some Cool Feature

A couple of days ago, Rails 4.2 is officially launched. There are a couple of feature that I know I will be glad for. One thing is adequate records that make simple query like ‘find’ is faster. Aaron Patterson’s blog cover the details of adequate records.

Other thing that will be useful is the active job. Active job is an adapter for various queuing system like Resque, Sidekiq, Sucker Punch, Delayed Job, etc. This will come handy, for example when it’s time to graduate from Sucker Punch into something more sophisticated like sidekiq, I don’t have to rewrite the job.

Web console is also interesting, though some of my friends said that this make the current Rails bloated. I find this feature is fun. See the gem page for some demos.

You can see the complete features list in the release notes.

Just to celebrate, I upgraded brentimana.com to Rails 4.2. By following the upgrading guide, I manage the upgrades without many glitches. In brentimana’s case, I just had to watch out about the responders, that now has been extracted into the responders gem. Voila, brentimana is now running on Rails 4.2

Brentimana on Rails 4.2
Brentimana on Rails 4.2

Actually, the new Rails has many small but useful “hidden” features. Justin Weiss cover them nicely here.

Single Process Asynchronous Job with Sucker Punch

In a previous post we discussed about running asynchronous job with sidekiq. Sidekiq will spawn it’s workers processes and look for jobs on queue. But what if we don’t want to use separate processes to do asynchronous job?

Enter sucker punch. ┬áSucker punch enable us to do asynchronous processing within a single job. ┬áThis will reduce memory usage in your hosting and reduce hosting cost in Heroku. I use it often when I develop a mockup on Heroku free hosting.It won’t be wrong to call it a poor men’s sidekiq.

Sucker punch is simple to use. I just want to remind you to take special precaution when interacting with active record in an asynchronous process. Use ActiveRecord::Base.connection_pool.with_connection to not exhaust the connection in the ppol, as per the example in the readme:

# app/jobs/awesome_job.rb

class AwesomeJob
  include SuckerPunch::Job

  def perform(user_id)
    ActiveRecord::Base.connection_pool.with_connection do
      user = User.find(user_id)
      user.update_attributes(is_awesome: true)
    end
  end
end

I also like to give some delay before starting an async job.

class Job
  include SuckerPunch::Job

  def perform(data)
    puts data
  end

  def later(sec, data)
    after(sec) { perform(data) }
  end
end

Job.new.async.perform("asdf")
Job.new.async.later(60, "asdf") # `perform` will be excuted 60 sec. later

So far sucker punch is my best friend when working with Heroku, since I’m a cheapskate, hahah.