Git: Issues with Gemfile.lock
When there's a Gemfile.lock
in your working directory that you cannot remove by either checkout
, reset [--hard]
, stash
, probably Rails' Spring is the culprit and not Bundler itself.
Fix
spring stop
The author of the linked Stackoverflow post supposes Spring re-writes the Gemfile.lock
on change to ensure all Spring processes are using the same gem versions. Meh.
Exclusive cronjobs with flock and whenever
I had a very frequent cronjob that in rare cases could be relatively slow. To avoid multiple instances of this cronjob running in parallel, I decided to use flock
to ensure that only one instance could run at a time.
flock
works by acquiring a lock to a file, and if it can do so running a command. In order not to wait but simply give up when the file is locked, you can add -n
:
flock /tmp/my.task.lock -n -c "bin/my-long-running-job"
Using whenever, and since this was a rake task, the follo...
Gemspecs must not list the same gem as both runtime and development dependency
When you're developing a gem, never list the same dependency as both runtime and development dependency in your .gemspec
.
So don't do this:
spec.add_dependency 'activesupport'
spec.add_development_dependency 'activesupport', '~> 2.3'
If you do this, your gemspec will not validate and modern versions of Bundler will silently ignore it. This leads to errors like:
Could not find your-gem-0.1.2 in any of the sources
What to do instead
If you want to freeze a different version of a dependency for your t...
Count number of existing objects in Ruby
Sometimes you want to know exactly how many objects exist within your running Ruby process. Here is how:
stats = {}
ObjectSpace.each_object {|o| stats[o.class].nil? ? stats[o.class] = 0 : stats[o.class] += 1 }; stats
=> {String=>192038, Array=>67690, Time=>2667, Gem::Specification=>2665, Regexp=>491, Gem::Requirement=>16323, Gem::StubSpecification=>2665, ...}
Maybe you want to sort it like this:
stats.sort_by {|k,v| v }
ExceptionNotification gem will only show application backtrace starting on Rails 4
Starting with Rails 4.0, when you get an exception reported via the ExceptionNotification
gem, you will only see a very short backtrace with all backtrace lines from gems or ruby libraries missing.
This happens, because the ExceptionNotification
gem uses Rails' default backtrace cleaner. To get a full backtrace in exception emails, you can remove the comment from this line in config/initializers/backtrace_silencers.rb
:
Rails.backtrace_cleaner.remove_silencers!
Note that this will break the "Application Trace" functionality o...
OR-ing query conditions on Rails 4 and 3.2
Rails 5 will introduce ActiveRecord::Relation#or
. On Rails 4 and 3.2 you can use the activerecord_any_of
gem which seems to be free of ugly hacks and nicely does what you need.
Use it like this:
User.where.any_of(name: 'Alice', gender: 'female')
^
SELECT "users".* FROM "users" WHERE (("users"."name" = 'Alice' OR "users"."gender" = 'female'))
To group conditions, wrap them in hashes:
User.where.any_of({ name: 'Alice', gender: 'female' }, { name: 'Bob' }, { name: 'Charl...
httpclient: A Ruby HTTP client for serious business
While debugging an intricate issue with failed HTTP requests I have come to appreciate the more advanced features of the httpclient Rubygem.
The gem is much more than a lightweight wrapper around Ruby's net/http
. In particular:
- A single
HTTPClient
instance can re-use persistent connections across threads in a thread-safe way. - Has a custom and configurable SSL certificate store (which you probably want to disable by default...
Error installing gem with native extension (collect2: error: ld returned 1 exit status)
If you have problems installing a gem and get a error collect2: error: ld returned 1 exit status
it's due to missing development headers of a library (ld
is the linker).
For example, with this output:
$ gem install json
Building native extensions. This could take a while...
ERROR: Error installing json:
ERROR: Failed to build gem native extension.
/home/foobar/.rvm/rubies/ruby-2.2.3/bin/ruby -r ./siteconf20150915-3539-1i9layj.rb extconf.rb
creating Makefile
make "DESTDIR=" clean
make "DESTDIR="
compiling generator.c...
How to update RubyGems binary for all installed rubies
To update your Rubygems to the latest available version, type the following:
gem update --system
Note that you have a separate Rubygems installation for each Ruby version in your RVM or rbenv setup. Updating one does not update the others.
Ruby 1.8.7
If you are using Ruby 1.8.7 you cannot use the latest version of Rubygems. Type the following to get the latest version that is compatible with 1.8.7:
gem updat...
whenever: Preview the crontab
If you'd like to preview the crontab that whenever will deploy, run the following:
bundle exec whenever
This will print the cron syntax without modifying your local crontab.
List RubyGems binary version for all installed Ruby versions
rbenv
To check which rubygems versions your different rbenv rubys are using, you can use this small bash script:
for i in $(rbenv versions --bare); do rbenv shell "${i}"; echo -n "ruby ${i} has gem version: "; gem -v; done
RVM
rvm all do gem -v
marco-polo improves your Rails console prompt
MarcoPolo shows your app name and environment in your console prompt so you don't accidentally break production
Officially supporting IRB (standard rails console) and pry (via pry-rails gem).
Example:
$ rails console
Loading development environment (Rails 4.2.1)
agencyapp(dev)>
How to enable SSL in development with Passenger standalone
Here is how to start your Rails application to accept both HTTP and HTTPS in development.
-
gem install passenger
-
Create a self-signed SSL certificate. Store the generated files in config/passenger-standalone-ssl.
-
Create a Passengerfile.json at the project root with this content (or save the attached file):
{ "ssl": true, "ssl_port": 3001, "ssl_certificate": "config/passenger-standalone-ssl/server.crt",
...
Detecting N+1 queries with Bullet
The Bullet gem is designed to help you increase your application's
performance by reducing the number of queries it makes. It will watch
your queries while you develop your application and notify you when
you should add eager loading (N+1 queries), when you're using eager
loading that isn't necessary and when you should use counter cache.
emcien/iso_latte
Sometimes you need to run background jobs that you can't make important guarantees about - they may run out of memory and get killed, or produce segmentation faults, or exit! directly - and you need to be able to clean up after such problems.
IsoLatte is a gem that allows a block of code to be executed in a subprocess. Exceptions get passed back to the parent process through a pipe, and various exit conditions are handled via configurable callbacks.
ZenTest "invalid gemspec" / "Illformed requirement"
Today I ran into this:
Invalid gemspec in [/usr/local/rvm/gems/ruby-1.9.3-p194/specifications/ZenTest-4.9.3.gemspec]: Illformed requirement ["< 2.1, >= 1.8"].
You need a newer Rubygems version. Try this: gem update --system 1.8.29
Upgrading from Capistrano 2 to 3
Capistrano 3 is a major rework of the framework and requires several adjustments to your deploy configuration files. The biggest change is that they moved away from their custom DSL and use Rake
instead. For connecting with and operating on the servers, they bring a new gem SSHKit
which does the heavy lifting. It's SSHKit's DSL that is used anywhere inside the Rake tasks. See #Resources at the bottom for examples.
Step 1: Upgrade guide
For migration from 2 to 3, follow this tutorial: [Capistrano 3 Upgrade Guide](https://semaphorec...
RSpec: Tagging examples and example groups
In RSpec you can tag examples or example groups with any tags you like simply by saying
describe ReportCreator, slow: true do
# ..
end
describe ReportCreator do
it 'generates reports', slow: true do
# ...
end
end
You can then only run examples with these tags.
rspec --tag slow
rspec -t slow
# Using the parallel_tests gem
rake "parallel:spec[,,--tag slow]"
Or you can run all examples except the ones with a certain tag:
rspec --tag ~slow # note the ~
rspec -t ~slow
# Using the parallel_tests gem
r...
Thread-safe collections in Ruby
When using threads, you must make your code thread-safe. This can be done by either locking (mutexes) all data shared between threads, or by only using immutable data structures. Ruby core classes like String
or Array
are not immutable.
There are several gems providing thread-safe collection classes in Ruby.
concurrent-ruby
The concurrent-ruby gem provides thread-safe versions of Array
and Hash
:
sa = Concurrent::Array.new # supports standard Array.new forms
sh = Co...
Differences between transactions and locking
Web applications can be used by multiple users at the same time. A typical application server like Passenger has multiple worker processes for a single app. In a distributed deployment setup like we use at makandra you will even have multiple application servers, each with their own worker pool.
This means that your code needs to deal with concurrent data access. The two main tools we use to cope with concurrency are database transactions and distributed locks. These two are not interchangeable. You ca...
Dusen (>0.5) now with "exclude from search"
Dusen (our search gem) is now capable of excluding words, phrases and qualified fields from search.
E.g. search for
included -excluded
"search this" -"not that"
topic:"Yes" -topic:"No"
This will soon also work in makandra cards!
Slack integration for deployments via Capistrano
You can hook into Slack when using Capistrano for deployment. The slackistrano gem does most of the heavy lifting for you. Its default messages are unobtrusive and can be adjusted easily.
When deploying, it posts to a Slack channel like this:
How to integrate
Integrating Slackistrano with Capistrano 3 is fairly simple.
- In your Slack, open menu → A...
Exporting to Excel from Rails without a gem
See this Railscast.
Basically you can simply write views like index.xlsx.erb
:
<?xml version="1.0"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet ss:Name="Sheet1">
<Table>
<Row>
<Cell><Data ss:Type="String">ID</Data></Ce...
Fix error UDPSocket.open: wrong number of arguments (0 for 1)
I got the following error after updating the selenium-webdriver
gem:
wrong number of arguments (0 for 1) (ArgumentError)
/home/pointoo-dev/.rvm/gems/ruby-1.8.7-p374/gems/selenium-webdriver-2.35.1/lib/selenium/webdriver/common/platform.rb:183:in `open'
/home/pointoo-dev/.rvm/gems/ruby-1.8.7-p374/gems/selenium-webdriver-2.35.1/lib/selenium/webdriver/common/platform.rb:183:in `ip'
/home/pointoo-dev/.rvm/gems/ruby-1.8.7-p374/gems/selenium-webdriver-2.35.1/lib/selenium/webdriver/common/platform.rb:196:in `interfaces'
It was caused...