How to undo a wrong ‘bundle install’

Sometimes I inadvertently run ´$ bundle install´ before setting to the right gemset through rvm, and thus messing up the current (and wrong) gemset.

$ gem list

*** LOCAL GEMS ***

actionmailer (3.2.12)
actionpack (3.2.12)
active_utils (1.0.5)
activemerchant (1.31.1)
activemodel (3.2.12)
activerecord (3.2.12)
activerecord-import (0.3.1)
activeresource (3.2.12)
activesupport (4.0.4, 3.2.12)
acts_as_list (0.2.0)
airbrake (3.1.8)
allison (2.0.3)
ansi (1.4.3)
ar-extensions (0.9.2)
archive-tar-minitar (0.5.2)
arel (3.0.2)
atomic (1.1.16)
attr_required (0.0.5)
authlogic (3.2.0, 2.1.6)
authlogic_rpx (1.2.0)
aws-sdk (1.8.5)
bourne (1.1.2)
builder (3.2.2, 3.0.4)
bundler (1.2.3)
cane (2.6.1)
childprocess (0.3.9)
chronic (0.9.1)
ci_reporter (1.9.1)
climate_control (0.0.3)
cocaine (0.5.1)
coderay (1.1.0, 1.0.9)
columnize (0.3.6)
contacts19 (1.2.4)
coveralls (0.7.0)
daemon_controller (1.1.1)
daemons (1.1.9)
docile (1.1.3)
echoe (4.6.3)
elasticsearch (1.0.1)
elasticsearch-api (1.0.1)
elasticsearch-extensions (0.0.14)
elasticsearch-transport (1.0.1)
erubis (2.7.0)
eventmachine (1.0.1)
factory_girl (4.2.0)
faraday (0.9.0, 0.8.6)
fastthread (1.0.7)
fattr (2.2.1)
ffi (1.4.0)
gdata_19 (1.1.5)
gem-wrappers (1.2.4)
gemcutter (0.7.1)
guard (1.6.2)
guard-spork (1.5.0)
guard-test (0.7.0)
has_many_polymorphs (2.13)
hashie (2.0.5, 2.0.2)
highline (1.6.15)
hike (1.2.1)
hominid (3.0.5)
hpricot (0.8.6)
httmultiparty (0.3.8)
httparty (0.10.2)
httpauth (0.2.0)
httpclient (2.3.3)
i18n (0.6.9, 0.6.4)
itunes-search (0.4.1)
journey (1.0.4)
json (1.7.7)
json_pure (1.7.7)
jwt (0.1.6)
linecache19 (0.5.13)
listen (0.7.3)
lumberjack (1.0.2)
macaddr (1.6.1)
mail (2.4.4)
metaclass (0.0.4, 0.0.1)
method_source (0.8.2, 0.8.1)
mime-types (2.2, 1.21)
minitest (4.7.5)
mocha (1.0.0, 0.10.5)
money (5.1.1)
multi_json (1.9.0, 1.6.1)
multi_xml (0.5.3)
multipart-post (2.0.0, 1.2.0)
music_xray_api (0.3.0)
mysql2 (0.3.11)
newrelic_rpm (3.5.8.72)
nokogiri (1.5.6)
oauth (0.4.7)
oauth-plugin (0.4.1)
oauth2 (0.9.1)
options (2.3.0)
paperclip (3.4.1)
parallel (0.9.2)
passenger (3.0.19)
paypal-express (0.5.3)
polyglot (0.3.3)
pr_geohash (1.0.0)
progress_bar (0.4.0)
pry (0.9.12.6, 0.9.12)
pusher (0.11.3)
rack (1.5.2, 1.4.5)
rack-cache (1.2)
rack-protection (1.4.0)
rack-ssl (1.3.3)
rack-test (0.6.2)
rails (3.2.12)
railties (3.2.12)
rake (10.1.1, 10.0.3)
rb-fsevent (0.9.3)
rb-inotify (0.9.0)
rdiscount (2.0.7.1)
rdoc (3.12.2, 3.12.1)
rdoc-data (3.12)
redis (3.0.3)
redis-namespace (1.2.1)
require-prof (0.0.1)
resque (1.23.0)
resque-retry (1.0.0)
resque-scheduler (2.0.0)
resque_unit (0.4.4)
rest-client (1.6.7)
restclient_with_cert (0.0.8)
rmagick (2.13.2)
rpx_now (0.6.23)
rsolr (1.0.8)
ruby-debug-base19x (0.11.30.pre10)
ruby-debug-ide (0.4.17.beta17, 0.4.17.beta16)
ruby-mp3info (0.8)
ruby-mysql (2.9.10)
ruby-prof (0.14.2)
ruby_core_source (0.1.5)
rubyforge (2.0.4)
rubygems-bundler (1.1.0)
rufus-scheduler (2.0.18)
rvm (1.11.3.5)
sanitize (2.0.3)
shoulda (3.3.2)
shoulda-context (1.1.6, 1.0.2)
shoulda-matchers (1.4.2)
signature (0.1.6)
simplecov (0.8.2)
simplecov-html (0.8.0)
simplecov-rcov (0.2.3)
sinatra (1.3.5)
slop (3.5.0, 3.4.3)
soundcloud (0.3.1)
spork (0.9.2)
spork-testunit (0.0.8)
sprockets (2.2.2)
sunspot (2.0.0)
sunspot_rails (2.0.0)
systemu (2.5.2)
term-ansicolor (1.3.0)
terminal-table (1.4.5)
test-unit (2.5.4)
thin (1.5.0)
thor (0.18.1, 0.17.0)
thread_safe (0.3.0)
tilt (1.3.4)
tins (1.0.0)
treetop (1.4.12)
turn (0.9.7)
tzinfo (0.3.39, 0.3.36)
useragent (0.4.16)
uuid (2.3.7)
uuidtools (2.1.3)
validatable (1.6.7)
vegas (0.1.11)
will_paginate (3.0.4)
xml-simple (1.1.2)
yard (0.8.7.3)
yui-on-rails (0.1.16)

For example, the above ´$ gem list´ shows old gems (normal text) from an old Rails 3 project mixed up with new gems (bold text) from a new Rails 4 project. At a certain point in my terminal session I had run ´$ rvm use ruby-1.9.3-p327@old-rails3-project´ and some time (days?) later I edited my new project’s Gemfile and ran ´$ bundle install´.

To fix the mess, I’ve written the following command line:

$ threshold="2d"; dir="`rvm gemdir`/gems"; find -X "$dir" -type d -maxdepth 1 -mindepth 1 -mtime -"$threshold" | xargs basename | sed -e 's/-(([0-9]{1,}.)*[0-9]{1,})$/ 1/g' -e 's/(.*) (.*)/gem uninstall 1 --version 2 --executables --ignore-dependencies &/g'

Which in my case generated the following command lines:

gem uninstall activesupport –version 4.0.4 –executables –ignore-dependencies &
gem uninstall ansi –version 1.4.3 –executables –ignore-dependencies &
gem uninstall atomic –version 1.1.16 –executables –ignore-dependencies &
gem uninstall builder –version 3.2.2 –executables –ignore-dependencies &
gem uninstall cane –version 2.6.1 –executables –ignore-dependencies &
gem uninstall ci_reporter –version 1.9.1 –executables –ignore-dependencies &
gem uninstall coderay –version 1.1.0 –executables –ignore-dependencies &
gem uninstall coveralls –version 0.7.0 –executables –ignore-dependencies &
gem uninstall docile –version 1.1.3 –executables –ignore-dependencies &
gem uninstall elasticsearch –version 1.0.1 –executables –ignore-dependencies &
gem uninstall elasticsearch-api –version 1.0.1 –executables –ignore-dependencies &
gem uninstall elasticsearch-extensions –version 0.0.14 –executables –ignore-dependencies &
gem uninstall elasticsearch-transport –version 1.0.1 –executables –ignore-dependencies &
gem uninstall faraday –version 0.9.0 –executables –ignore-dependencies &
gem uninstall hashie –version 2.0.5 –executables –ignore-dependencies &
gem uninstall i18n –version 0.6.9 –executables –ignore-dependencies &
gem uninstall metaclass –version 0.0.4 –executables –ignore-dependencies &
gem uninstall method_source –version 0.8.2 –executables –ignore-dependencies &
gem uninstall mime-types –version 2.2 –executables –ignore-dependencies &
gem uninstall minitest –version 4.7.5 –executables –ignore-dependencies &
gem uninstall mocha –version 1.0.0 –executables –ignore-dependencies &
gem uninstall multi_json –version 1.9.0 –executables –ignore-dependencies &
gem uninstall multipart-post –version 2.0.0 –executables –ignore-dependencies &
gem uninstall parallel –version 0.9.2 –executables –ignore-dependencies &
gem uninstall pry –version 0.9.12.6 –executables –ignore-dependencies &
gem uninstall rake –version 10.1.1 –executables –ignore-dependencies &
gem uninstall require-prof –version 0.0.1 –executables –ignore-dependencies &
gem uninstall ruby-prof –version 0.14.2 –executables –ignore-dependencies &
gem uninstall shoulda-context –version 1.1.6 –executables –ignore-dependencies &
gem uninstall simplecov –version 0.8.2 –executables –ignore-dependencies &
gem uninstall simplecov-html –version 0.8.0 –executables –ignore-dependencies &
gem uninstall simplecov-rcov –version 0.2.3 –executables –ignore-dependencies &
gem uninstall slop –version 3.5.0 –executables –ignore-dependencies &
gem uninstall term-ansicolor –version 1.3.0 –executables –ignore-dependencies &
gem uninstall thor –version 0.18.1 –executables –ignore-dependencies &
gem uninstall thread_safe –version 0.3.0 –executables –ignore-dependencies &
gem uninstall tins –version 1.0.0 –executables –ignore-dependencies &
gem uninstall turn –version 0.9.7 –executables –ignore-dependencies &
gem uninstall tzinfo –version 0.3.39 –executables –ignore-dependencies &
gem uninstall yard –version 0.8.7.3 –executables –ignore-dependencies &

Then it’s just a matter of (reviewing and) copy-and-pasting those lines (either individually or all at once) into the command prompt and the old gemset will return to its old state.

$ gem list

*** LOCAL GEMS ***

actionmailer (3.2.12)
actionpack (3.2.12)
active_utils (1.0.5)
activemerchant (1.31.1)
activemodel (3.2.12)
activerecord (3.2.12)
activerecord-import (0.3.1)
activeresource (3.2.12)
activesupport (3.2.12)
acts_as_list (0.2.0)
airbrake (3.1.8)
allison (2.0.3)
ar-extensions (0.9.2)
archive-tar-minitar (0.5.2)
arel (3.0.2)
attr_required (0.0.5)
authlogic (3.2.0, 2.1.6)
authlogic_rpx (1.2.0)
aws-sdk (1.8.5)
bourne (1.1.2)
builder (3.0.4)
bundler (1.2.3)
childprocess (0.3.9)
chronic (0.9.1)
climate_control (0.0.3)
cocaine (0.5.1)
coderay (1.0.9)
columnize (0.3.6)
contacts19 (1.2.4)
daemon_controller (1.1.1)
daemons (1.1.9)
echoe (4.6.3)
erubis (2.7.0)
eventmachine (1.0.1)
factory_girl (4.2.0)
faraday (0.8.6)
fastthread (1.0.7)
fattr (2.2.1)
ffi (1.4.0)
gdata_19 (1.1.5)
gem-wrappers (1.2.4)
gemcutter (0.7.1)
guard (1.6.2)
guard-spork (1.5.0)
guard-test (0.7.0)
has_many_polymorphs (2.13)
hashie (2.0.2)
highline (1.6.15)
hike (1.2.1)
hominid (3.0.5)
hpricot (0.8.6)
httmultiparty (0.3.8)
httparty (0.10.2)
httpauth (0.2.0)
httpclient (2.3.3)
i18n (0.6.4)
itunes-search (0.4.1)
journey (1.0.4)
json (1.7.7)
json_pure (1.7.7)
jwt (0.1.6)
linecache19 (0.5.13)
listen (0.7.3)
lumberjack (1.0.2)
macaddr (1.6.1)
mail (2.4.4)
metaclass (0.0.1)
method_source (0.8.1)
mime-types (1.21)
mocha (0.10.5)
money (5.1.1)
multi_json (1.6.1)
multi_xml (0.5.3)
multipart-post (1.2.0)
music_xray_api (0.3.0)
mysql2 (0.3.11)
newrelic_rpm (3.5.8.72)
nokogiri (1.5.6)
oauth (0.4.7)
oauth-plugin (0.4.1)
oauth2 (0.9.1)
options (2.3.0)
paperclip (3.4.1)
passenger (3.0.19)
paypal-express (0.5.3)
polyglot (0.3.3)
pr_geohash (1.0.0)
progress_bar (0.4.0)
pry (0.9.12)
pusher (0.11.3)
rack (1.5.2, 1.4.5)
rack-cache (1.2)
rack-protection (1.4.0)
rack-ssl (1.3.3)
rack-test (0.6.2)
rails (3.2.12)
railties (3.2.12)
rake (10.0.3)
rb-fsevent (0.9.3)
rb-inotify (0.9.0)
rdiscount (2.0.7.1)
rdoc (3.12.2, 3.12.1)
rdoc-data (3.12)
redis (3.0.3)
redis-namespace (1.2.1)
resque (1.23.0)
resque-retry (1.0.0)
resque-scheduler (2.0.0)
resque_unit (0.4.4)
rest-client (1.6.7)
restclient_with_cert (0.0.8)
rmagick (2.13.2)
rpx_now (0.6.23)
rsolr (1.0.8)
ruby-debug-base19x (0.11.30.pre10)
ruby-debug-ide (0.4.17.beta17, 0.4.17.beta16)
ruby-mp3info (0.8)
ruby-mysql (2.9.10)
ruby_core_source (0.1.5)
rubyforge (2.0.4)
rubygems-bundler (1.1.0)
rufus-scheduler (2.0.18)
rvm (1.11.3.5)
sanitize (2.0.3)
shoulda (3.3.2)
shoulda-context (1.0.2)
shoulda-matchers (1.4.2)
signature (0.1.6)
sinatra (1.3.5)
slop (3.4.3)
soundcloud (0.3.1)
spork (0.9.2)
spork-testunit (0.0.8)
sprockets (2.2.2)
sunspot (2.0.0)
sunspot_rails (2.0.0)
systemu (2.5.2)
terminal-table (1.4.5)
test-unit (2.5.4)
thin (1.5.0)
thor (0.17.0)
tilt (1.3.4)
treetop (1.4.12)
tzinfo (0.3.36)
useragent (0.4.16)
uuid (2.3.7)
uuidtools (2.1.3)
validatable (1.6.7)
vegas (0.1.11)
will_paginate (3.0.4)
xml-simple (1.1.2)
yui-on-rails (0.1.16)

How it works

First you set in my command above the threshold time that you consider safe for detecting all the wrong gems (´threshold=”2d”´). It can be anything from s-econds to w-eeks. Then, when you run my command

  1. it detects the current gemdir
    ´dir=”`rvm gemdir`/gems”´
  2. it finds all the directories contained in the gemdir which were modified after the threshold time
    ´find -X “$dir” -type d -maxdepth 1 -mindepth 1 -mtime -“$threshold”´
  3. for each directory, it removes the gemdir prefix
    ´xargs basename´
  4. for each directory, it detects the gem’s name and the gem’s version
    ´sed -e ‘s/-\(\([0-9]\{1,\}.\)*[0-9]\{1,\}\)$/ \1/g’´
  5. for each gem/version, it displays a command for uninstalling that version of that gem in background
    ´sed -e ‘s/\(.*\) \(.*\)/gem uninstall \1 –version \2 –executables –ignore-dependencies \&/g’´

REMEMBER that the current gemset MUST be the messed up one.

How to test Paperclip uploads in Rails4

When testing Paperclip uploads in my application, I’m interested in treating Paperclip as a black box and trusting it for doing its magic. So what I really need to test is that valid files are processed and invalid ones are not. (see How to allow users to crop images in Rails 4 for model and controller code)

Tests for the model:

{[ .model-tests | 1.hljs(=ruby=) ]}

Tests for the controller:

{[ .controller-tests | 1.hljs(=ruby=) ]}

 

How to allow users to crop images in Rails 4

For cropping images I use Jcrop, a plugin for jQuery. It works pretty well and there are already some tutorials for integrating it into a Rails app. So this post is almost a simple update to what’s already available in the internet. What follows is just my setup.

1: create an Upload model, i.e. a class for holding uploaded files, not only images. This is fairly straightforward.

{[ .migration-basic | 1.hljs(=ruby=) ]}

{[ .upload-class-basic | 1.hljs(=ruby=) ]}

2: attach Paperclip to the Upload model.

{[ .gem-cargo | 1.hljs(=ruby=) ]}

{[ .migration-cargo | 1.hljs(=ruby=) ]}

Note that in my setup, contrary to what’s generally advised, I’m trashing the really original image in favor of a (small and) predictable version of it. (width, height and weight)

{[ .upload-class-cargo | 1.hljs(=ruby=) ]}

3: add exif data support

{[ .gem-exif | 1.hljs(=ruby=) ]}

{[ .migration-exif | 1.hljs(=ruby=) ]}

{[ .upload-class-exif | 1.hljs(=ruby=) ]}

4: add cropping support

Jcrop must be installed in Rails.

  1. I added a /vendor/assets/jquery-jcrop/0.9.2 directory with all of its files in it.
  2. I copied js/jquery-Jcrop.js, css/jquery-Jcrop.css and Jcrop.gif into the /vendor/assets/jquery-jcrop directory.
  3. I added a = require jquery.Jcrop line into both the /app/assets/javascripts/application.js and /app/assets/stylesheets/application.css manifests.

{[ .manual-thumbnail | 1.hljs(=ruby=) ]}

{[ .migration-crop | 1.hljs(=ruby=) ]}

{[ .upload-class-crop | 1.hljs(=ruby=) ]}

5: modify the generated controller such that

  1. all necessary params are whitelisted
  2. upon image creation the user is given a chance to crop it
  3. upon image update it gets cropped

{[ .uploads-controller | 1.hljs(=ruby=) ]}

6: modify the form helper

{[ .form-helper | 1.hilite(=html=) ]}

7: modify the show template

{[ .show-template | 1.hilite(=html=) ]}