How to update a single gem conservatively

The problem

Calling bundle update GEMNAME will update a lot more gems than you think. E.g. when you do this:

bundle update cucumber-rails

... you might think this will only update cucumber-rails. But it actually updates cucumber-rails and all of its dependencies. This will explode in your face when one of these dependencies release a new version with breaking API changes. Which is all the time.

In the example above updating cucumber-rails will give you Capybara 2.0 (because capybara is a dependency of `cucumber-rail...

Running "bundle update" without arguments might break your application

Calling bundle update (without arguments) updates all your gems at once. Given that many gems don't care about stable APIs, this might break your application in a million ways.

To stay sane, update your gems using the applicable way below:

Projects in active development

Update the entire bundle regularily (e.g. once a week). This ensures that your libraries are up-to-date while it's easy to spot major version bumps which may break the app.

Projects that have not been updated in a while

  1. [Update a single gem conservatively](htt...

RVM: Get rid of your system Ruby

If you worked with a system Ruby before switching to RVM, this system Ruby will be in your way when you switch between projects with/without RVM.

It's hard to get rid of your system Ruby entirely, but you can tell RVM to just use a given Ruby by default, e.g.:

rvm --default use 1.8.7

You need to re-open existing terminals for the changes to take effect.

Note that this will not actually remove the ruby package from your system, it just isn't used anymore.

Ruby: How to ensure a Tempfile's extension

If you use Tempfile and pass your own filename containing an extension, it will just be consumed by the Tempfile's filename:

>> Tempfile.new('foobar.xlsx').path
=> "/tmp/foobar.xlsx20130115-19153-4ykpwm-0"

If you want to keep the file extension, pass filename and extension as an array:

>> Tempfile.new([ 'foobar', '.xlsx' ]).path
=> "/tmp/foobar20130115-19153-1xhbncb-0.xlsx"

How to get the hostname of the current machine in Rails or a Ruby script

Use Socket.gethostname. So for a machine whose hostname is "happycat", it will look like this:

>> Socket.gethostname
=> "happycat"

That should work right away for your Rails application. For plain Ruby, you first need to do:

require 'socket'

If you don't want to use Socket for some reason, you can still just use the hostname command, at least on non-Windows machines. Keep in mind that you need to remove trailing white space from the result of the system call.

>> `hostname`
=> "happycat\n"
>> `hostname`.stri...

Fix error: undefined method `desc' for #<Foo::Rake::Taskx1234>

Upgrade the offending gem. If you cannot or don't want to upgrade, lock rake to 0.8.7.

will_paginate can paginate plain Ruby arrays

While you are probably using will_paginate to paginate ActiveRecord scopes, it can actually paginate plain Ruby arrays. The resulting arrayish object will have the same methods as a paginated scope, e.g. #total_entries. This means you can render pagination controls with the same code that works with paginated scopes.

To enable this, add an initializer config/initializers/array_paginate.rb:

require 'will_paginate/array'

You can now say:

> numbers = (1..1000).to_a
> page = numbers....

Rails 4 Countdown to 2013 | The Remarkable Labs Blog

With the impending release of Ruby on Rails 4, it looks like a lot of developers will be updating their web applications in the coming new year.

To help with this transition, over the next 31 days, we are going to be releasing a series of blog posts going over everything you will need to know about Rails 4 for an effortless upgrade.

Error installing ffi gem

Do this before you install the gem:

 sudo apt-get install libffi-dev

King of Nothing, the DCI paradigm is a scam

I’ve worked on huge applications in Ruby and Rails before. I very much want to believe in DCI, but I’m having a hard time accepting the promises of Clean Ruby when it seems like the work on this paradigm is half-done. If it weren’t so oversold and hyped, I think I’d be more patient, but right now I’m just frustrated and confused.

randym/axlsx · GitHub

Axlsx is an incredible gem to generate "Office Open XML" spreadsheet files (XLSX). Does not break on large spreadsheets and supports a ton of features like graphs.

API looks mature and existing code is easy to migrate when coming from the spreadsheet gem.
The documentation of some methods is a bit out of date, but you'll find your way around the gem's code.

No support for reading files, however. :( If you want to open XLSX spreadsheets (for example to confirm your output in tests), you can use [roo](h...

RSpec: Defining helper methods for an example group

You can define methods in any example group using Ruby's def keyword or define_method method:

describe "example" do
  def sum(a, b)
    a + b
  end

  it "has access to methods defined in its group" do
    expect(sum(3, 4)).to be(7)
  end
end

The helper method is also available to groups nested within that group. The helper method is not available to parent or sibling groups.

Global helpers

To define helpers for all specs (or all specs of a type), [define it in a module](https://rspec.info/features/3-12/rspec-core/help...

Everything you ever wanted to know about constant lookup in Ruby

If you ever wondered why a constant wasn't defined or wasn't available where you expected it to be, this article will help.

Also see Ruby constant lookup: The good, the bad and the ugly.

How to package a non-Ruby file into a gem

Great solution in a GitHub issue.

Cronjobs: "Craken" is dead, long live "Whenever"

Our old solution for cronjobs, the "craken" plugin, is no longer maintained and does not work on Rails 3.2+.

We will instead use the whenever gem.

"Whenever" works just like "craken", by putting your rake tasks into the server's cron table. Everything seems to work just like we need it.

Installation for new projects

  1. Add "whenever" to your Gemfile:

     group :deploy do
       gem 'whenever', require: false
     end
    
  2. Add it to your config/deploy.rb:
    ...

navy gem: Hide empty navigation bars

navy 0.5.1+ gives empty navigation containers a CSS class .navy-empty which you can hide via

.navy-navigation
  &.navy-empty
    display: none

SearchableTrait is now a gem: Dusen

For two years we've been using SearchableTrait which gives models the ability to process Googlesque queries like this:

Contact.search('a mix of words "and phrases" and qualified:fields')

This trait used to be a huge blob of code without tests and documentation, so I made a gem out of it. Check out https://github.com/makandra/dusen for code, tests, and a huge README.

You should use the Dusen gem and delete SearchableTrait in all future projects.

Note that the syntax to define query proc...

byebug / ruby-debug: Find out current debugger position

So you are debugging like a boss and lost track of where you actually are in your code? No problem:

  • Calling "l=" will show you the current file and line. That's a lower-case L and an equals sign.
  • "where" (or "backtrace") will give you the debugger call stack, including current file and line as well. It can be quite long.

Zeus promises to make rails development faster

I am talking about development speed. When your application starts growing and you start adding gems, it starts to take really long to start up, be it the server, console or just running a single spec.

Zeus is smart, you don’t have to put it in your Gemfile or run it with Bundler, all you need to do is create a JSON config file via zeus init and then start the server zeus start.

After that, you’re ready to go, all you need to do is prefix every command with zeus. That means rails server becomes zeus server, `rails console...

Capybara 2.0 has been released

The gem author Jonas Nicklas highlights in a Google Groups post that the release

  • is not backwards compatible to 1.x versions of Capybara
  • does not support Ruby 1.8.x anymore
  • removes confusion with Rails' built in integration tests (you put capybara rspec integration tests into the spec/feature/... folder) and the :type metadata has been changed from :request to :feature
  • throws exceptions when trying to interact with an element whose identifier is...

Andand and SimpleDelegator

The very useful andand gem does not play very nice with Ruby's SimpleDelegator (or vice versa).

This following will not work:

class MyDecorator < SimpleDelegator
  def foo
  end
end

MyDecorator.new(Object.new).andand.foo

The reasons are a bit subtle, basically SimpleDelegator will "force" some methods to be delegated, so the andand method is called on the wrapped object, not the delegator.

You can fix it like this:

class Decorator < SimpleDelegator
  def an...

Using sets for many-to-many relationships

A technique to vastly reduce the number of join model records that need to be stored in the database.

The technique is only effective when there is a high redundancy in your data, e.g. combinations of the same 20 tags are used to label thousands of books.

The technique is also limited in that your join models cannot have additional logic, such as attributes or callbacks.

Ther has-many-with-set gem is an implementation of this technique.

uninitialized constant MysqlCompat::MysqlRes (NameError)

If you get a stacktrace complaining about uninitialized constant MysqlCompat::MysqlRes a system library update might broke your gem.

You might have switched from MySQL to MariaDB, but forgot to rebuild your MySQL gems.

Try fully removing and re-installing the gem:

gem uninstall mysql mysql2
bundle install

Rails: When to use :inverse_of in has_many, has_one or belongs_to associations

When you have two models in a has_many, has_one or belongs_to association, the :inverse_of option in Rails tells ActiveRecord that they're two sides of the same association.

Example with a has_many / belongs_to association:

class Forum < ActiveRecord::Base
  has_many :posts, inverse_of: :forum
end

class Post < ActiveRecord::Base
  belongs_to :forum, inverse_of: :posts
end

Knowing the other side of the same association Rails can optimize object loading so forum and forum.posts[0].forum will reference the same o...