Rails
Speed Up Your Specs
published Tuesday, February 11, 2014
Just a few references to help you boost your spec suites. Got 50% - 70% speed boost for BookingSync test suite.
- Inspect with perftools.rb
- Lower BCrypt Cost
- Deferer Garbage Collection
References:
http://blog.syncopelabs.co.uk/2012/12/speed-up-rspec-test.html
http://makandracards.com/makandra/950-speed-up-rspec-by-deferring-garbage-collection
http://blog.carbonfive.com/2011/02/02/crank-your-specs/
Rails with SSL in development with POW and Tunnelss
published Sunday, February 09, 2014
Updated 2014-09-17: Recommend Tunnelss (extra 's') instead of Tunnels to provide valid certificate for .dev domains. (Use carefully, .dev is now a legitimate TLD)
I'm using Pow for running Ruby on Rails Apps in development. One thing not provided by Pow but important to me, is the ability to use SSL in development. For this, I use Tunnelss
Once setup, you'll need to make it run everytime you start your computer, and on OS X Mavericks using rbenv, this can be done by creating the following file:
/Library/LaunchDaemons/org.rubygems.tunnelss.plist
Make sure to adjust the tunnels path to your system
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.rubygems.tunnelss</string>
<key>ProgramArguments</key>
<array>
<string>/Users/seb/.rbenv/shims/tunnelss</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>UserName</key>
<string>root</string>
</dict>
</plist>
Far Future Expiration Header for nginx
published Thursday, March 21, 2013
Rails 3.1+ and the Asset Pipeline is excellent to minify, merge, and deliver assets, however it's good to also leverage browser caching.
Using nginx, you can set a far future expiration header like this:
server {
location ~ ^/(assets)/ {
expires max;
}
}
Twitter Bootstrap and simple_form
published Monday, February 27, 2012
Updated: February 28th 2012 to fix a typo in the translation file. Thanks erwin.
Starting to work with Twitters Bootstrap I have to make few adaptation to my simple_form setup to keep having clean forms and benefit from the slick interface provided by Twitter Bootstrap.
The tweaks required takes 2 parts:
- The setup for input wrappers and form classes, ...
- The buttons wrappers to be added easily
Setup for input wrappers and form classes, ...
Most of the work can be done by generating your simple_form config with as describe on simple_form documentation
rails generate simple_form:install --bootstrap
I had to make a few extra tweaks to use the horizontal mode, that I prefer:
config.label_class = 'control-label'
config.form_class = 'simple_form form-horizontal'
That's now good for all except the submit buttons, I'm still not happy to define the whole submit wrapper on each form, so let's make a button wrapper
Buttons wrappers
Adding the following to a new library, for example /lib/extras/simple_form_extensions.rb:
module WrappedButton
def wrapped_button(*args, &block)
template.content_tag :div, :class => "form-actions" do
options = args.extract_options!
loading = self.object.new_record? ? I18n.t('simple_form.creating') : I18n.t('simple_form.updating')
options[:"data-loading-text"] = [loading, options[:"data-loading-text"]].compact
options[:class] = ['btn-primary', options[:class]].compact
args << options
if cancel = options.delete(:cancel)
submit(*args, &block) + ' ' + I18n.t('simple_form.buttons.or') + ' ' + template.link_to(I18n.t('simple_form.buttons.cancel'), cancel)
else
submit(*args, &block)
end
end
end
end
SimpleForm::FormBuilder.send :include, WrappedButton
will allow you to use :
<%= f.button :wrapped, :cancel => posts_path %>
Don't forget to load your new library, I like to use the following way from config/application.rb :
config.autoload_paths += %W(#{config.root}/lib/extras)
And require it from config/initializers/simple_form.rb
require 'simple_form_extensions'
Last thing, add the new translations within config/locales/simple_form.en.yml
en:
simple_form:
creating: "Creating..."
updating: 'Updating...'
buttons:
or: 'or'
cancel: 'cancel'
Restart your app server and here we go, we now keep the really clean way to manage forms of simple_form with the beautiful design of Twitter Bootstrap.
Rails 3.x export to CSV and TSV
published Wednesday, January 25, 2012
Register the TSV Mime Type
in `config/initializers/mime_types.rb` register the TSV mime type
Mime::Type.register "text/tab-separated-values", :tsv
Add to_csv and to_tsv to Arrays so as CSV and TSV renderers
In `lib/csv_and_tsv_renderers.rb`
# encoding: utf-8
#
require 'csv' # adds a .to_csv method to Array instances
class Array
BOM = "\xEF\xBB\xBF" #Byte Order Mark UTF-8
alias old_to_csv to_csv #keep reference to original to_csv method
def to_csv(options = Hash.new)
options = options.merge(:force_quotes => true)
# override only if first element actually has as_csv method
return old_to_csv(options) unless self.first.respond_to? :as_csv
# use keys from first row as header columns
out = first.as_csv.keys.collect{|k| k.to_s.titleize }.to_csv(options)
# collect all entries as CSV, ensure that no line break is present within values
self.each { |r| out << r.as_csv.values.to_csv(options).gsub(/\r?\n/, ' ').strip! + "\n" }
# Force encoding to UTF-16LE and add Byte Order Mark for Excel compatibility
(BOM + out).force_encoding("UTF-8")
end
def to_tsv(options = Hash.new)
to_csv(options.merge(:col_sep => "\t"))
end
end
ActionController::Renderers.add :csv do |csv, options|
csv = csv.respond_to?(:to_csv) ? csv.to_csv() : csv
self.content_type ||= Mime::CSV
self.response_body = csv
end
ActionController::Renderers.add :tsv do |tsv, options|
tsv = tsv.respond_to?(:to_tsv) ? tsv.to_tsv() : tsv
self.content_type ||= Mime::TSV
self.response_body = tsv
end
Load the lib
In `config/initializers/load_libs.rb`
require 'csv_and_tsv_renderers'
In your models
Cherry pick the attributes you like to be exported
def as_csv(options = {})
csv = {
attribute_1: attribute_1,
...
}
end
In your controllers
respond_to do |format|
...
format.csv { send_data @objects.to_csv(), :filename => "nice_filename.csv" }
format.tsv { send_data @objects.to_tsv(), :filename => "nice_filename.tsv" }
end
References
http://blog.plataformatec.com.br/2009/09/exporting-data-to-csv-and-excel-in-your-rails-app/
https://github.com/ilmotta/to-csv/issues/3
http://blog.grayproductions.net/articles/ruby_19s_string
http://stackoverflow.com/questions/539294/how-do-i-determine-file-encoding-in-osx
Update 2012-01-28
Use UTF-8 everywhere instead of the initial UTF-8 BOM then forcing to UTF-16LE. Seems to work fine under Windows' Office 2010.
If you could confirm that it works properly under an other version, opens fine and shows diacritics characters, please leave a comment bellow.