Asset pipeline may break Javascript for IE (but only on production)
If some of your JavaScripts fail on Internet Explorer, but only in staging or production environments, chances are that JavaScript compression is the culprit.
By default, Rails 3.2 compresses JavaScript with UglifyJS. I have seen a few cases where this actually breaks functioning JavaScript on IE (one example is the CKEditor).
I fixed this by switching to Yahoo's YUI Compressor.
To do this, do the following:
- replace the
uglifier
gem with theyui-compressor
gem...
Deal with error: Expected foo_trait.rb to define FooTrait
Lately, I came across a nasty error. I had a class Article
that included FooTrait
and BarTrait
. In BarTrait, I then accidentally called a non-existent method:
has_defaults :dummy => Dummy.non_existent_method
From that moment, no page would load anymore but always display an exception: Expected foo_trait.rb to define FooTrait
. That trait had nothing to do with BarTrait.
Since it doesn't tell you what's wrong, you either remember where you were working last or you need to check all [traits](https://github.com/makandra/modul...
PostgreSQL's OVERLAPS operator is not fully inclusive
PostgreSQL supports the SQL OVERLAPS
operator. You can use it to test if two date ranges overlap:
=> SELECT ('2001-02-16'::date, '2001-12-21'::date) OVERLAPS
('2001-12-20'::date, '2002-10-30'::date);
overlaps
--------
true
An important caveat is that the date ranges are defined as start <= time < end
. As such the later date is not included in the range:
=> SELECT ('2001-02-16'::date, '2001-12-21'::date) OVERLAPS
('2001-12-21'::date, '2002-10-30'::date);
overlaps
--------
false
Also compar...
has_defaults is now a gem
- has_defaults is now a gem, no longer a plugin.
- The plugin version no longer exists. Note that plugins are no longer supported in 3.2.
- If you are working on an application that has the plugin version of
has_defaults
there is no advantage to be gained from upgrading the gem. The gem is there for you should you one day upgrade to Rails 3.2+. - Please don't use the defaults gem which we original forked away from in 2009. It sets defaults when a field is `bl...
How to fix strangely disappearing or misbehaving forms
You most likely have a form
element inside another form
element. Don't do that. Ever.
Firefox and Chrome will discard the first form
nested inside another form
(but for some reason keep others). Internet Explorer will possibly act like nothing is wrong -- but break (send the outer form) when you submit.
If your application behaves normal at first but removes forms from the DOM when you Ajax around, this could be the cause. Remember this note when you think your browsers are broken once again and check for such things thoroughly bef...
Namespacing: why `uninitialized constant` error may occour in `development` but not in `test` environment
Example:
class Book::Page
end
class MyBook < Book
def new_page
Page.new # has to be `Book::Page` in development to make it work
end
end
Method new_page
may throw an error when it was called during browser interaction in development but doesn't make the test fail.
The reason
Development autoloading isn't smart enough to find the referenced class
At other environments (test, staging, production) autoloading is disabled, that all classes are already loaded when browser interaction takes place what makes...
How to find out if you are in Cucumber or in RSpec
Sometimes you need a piece of code to do something different for specs than for features. If you don't have separate environments, you can't check your Rails.env
.
I managed to distinguish between specs and features by asking Capybara
.
Note that this only works when you do not use Capybara in specs.
if defined?(Capybara) and Capybara.respond_to?(:current_driver)
# you're in a Cucumber scenario
else
# you're probably in a spec
end
You could omit the defined?(Capybara)
condition, if you are sure that Capybara
...
Distance of time in what you like: days, months, years
Sometimes the Rails helper #distance_of_time_in_words
is using too much magic.
When you need a time difference in a specific unit, use this method:
^
def distance_of_time_in(unit, from, to)
diff = to - from
if 1.respond_to? unit
distance = diff / 1.send(unit)
distance.abs.round
else
raise ArgumentError, "#{unit.inspect} is not supported as unit"
end
end
distance_of_time_in(:days, Time.now, 1.year.ago)
=> 365
Remove the .abs
if you want the mathematical *differ...
Iterate over every n-th element of a Range in Ruby
If you want to iterate over a Range, but only look at every n-th element, use the step
method:
(0..10).step(5).each do |i|
puts i
end
# Prints three lines:
# 0
# 5
# 10
This is useful e.g. to iterate over every Monday in a range of Dates
.
If you are using Rails or ActiveSupport, calling step
without a block will return an array of matching elements:
(0..10).step(5)
# => [0, 5, 10]
Cucumber: Detect if the current Capybara driver supports Javascript
Copy the attached file to features/support
. This gets you a convenience method:
Capybara.javascript_test?
Is true
for Selenium, capybara-webkit, Poltergeist and a custom driver called :chrome
(which we sometimes like to use for Selenium+Chrome).
Similar sounding but completely different card: Detect if a Javascript is running under Selenium WebDriver (with Rails)
Webrat doesn't follow redirect because it considers the url external
Rails doesn't know which host it is running on. For generating links, it strips the hostname off the request URL, which can lead to errors when you have absolute URLs in your Cucumber tests.
If you really need to use absolute URLs somewhere, say in an email you send, either throw away the host when parsing it (e.g. body.scan(/http:\/\/[^\/]+\/([^\s"<]+)/)
) or tell Webrat you're back on your site.
Different behavior for BigDecimal#floor in Ruby 1.8 and Ruby 1.9
Ruby 1.8 (supplied by Rails' ActiveSupport)
>> BigDecimal.new("0.1").floor.class
=> BigDecimal
Ruby 1.9 (supplied by Ruby 1.9 itself)
>> BigDecimal.new("0.1").floor.class
=> Fixnum
In fact, Float#floor
has changed from Ruby1.8 to Ruby 1.9 which is used by BigDecimal#floor
internally.
Attached initializer backports Ruby 1.9 behavior to Ruby 1.8.
How to fix webpack-dev-server not found
The bin/webpack-dev-server
command is not as smart as e.g. rails server
, where it shows the proper fix within the error message.
$ bin/webpack-dev-server
yarn run v1.19.1
error Command "webpack-dev-server" not found.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Run yarn install --check-files
to fix this error.
Fix when assigning nested attributes raises "undefined method `to_sym' for nil:NilClass"
You might have a table without a primary key set in MySQL.
You can fix this by adding a primary key index to the guilty MySQL table, or by setting self.primary_key = "id"
in your class definition.
Related, but different issue: Rails 2 does not find an association when it is named with a string instead of a symbol
Customize path for Capybara "show me the page" files
When you regularly make use of Cucumber's "show me the page" step (or let pages pop up as errors occur), the capybara-20120326132013.html
files will clutter up your Rails root directory.
To tell Capybara where it should save those files instead, put this into features/support/env.rb
:
Capybara.save_and_open_page_path = 'tmp/capybara'
Why your Cucumber feature loses cookies when run under Selenium
When your Cucumber feature seems to forget cookies / sessions when you run it with Selenium check if the test travels in time like here:
Given the date is 2017-10-20
When I sign in
Then I should see "Welcome!"
What happens here is that the Rails application serving pages runs in 2017, but the process running your browser still lives today. This huge gap in time will expire most cookies immediately.
If all you need is to freeze the time to a date, a workaround is to travel to the future instead.
Refile: Ruby file uploads, take 3
Jonas Nicklas, the author of Carrierwave and Capybara, has released Refile, a gem for handling file uploads in Rails. It handles direct uploads (also direct uploads to Amazon S3) better than Carrierwave.
The story and reasoning behind some of the decisions in Refile, and how it's different from Carrierwave, by the author himself, is a good read before deciding which way you'll go.
Big Caveat: Refile only stores the original image and r...
Look up a gem's version history
Sometimes it might be helpful to have a version history for a gem, e.g. when you want to see if there is a newer Rails 2 version of your currently used gem.
At first you should search your gem at RubyGems. Example: will_paginate version history.
The "Tags" tab at GitHub might be helpful as well.
Git error: "badTimezone: invalid author/committer line - bad time zone"
You might get the above error message when cloning certain git repositories (for example the rails repository). It indicates that there is a malformed timestamp in some commit, and your git installation is configured to validate it.
As a workaround, you can disable the validation using
git config --global fetch.fsckobjects false
This settings seems to be the default for most git installations anyways.
RSpec: Change the type of a spec regardless of the folder it lives in
In a Rails application, *_spec.rb
files get special treatment depending on the file's directory. E.g. when you put a spec in spec/controllers
your examples will have some magic context like controller
, post
or get
that appears out of nowhere.
If you want that magic context for a spec in another folder, use the :type
option:
describe CakesController, :type => :controller do
...
end
Fixing "uninitialized constant ActiveSupport::Dependencies::Mutex (NameError)"
RubyGems 1.6.0 has undergone some changes which may cause Rails 2.x applications to break with an error like this one (e.g. when running script/server):
/usr/lib/ruby/gems/1.8/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:55: uninitialized constant ActiveSupport::Dependencies::Mutex (NameError)
Fix it by adding the following not only to your environment.rb but also into your script/server file, in both cases before boot.rb
is required.
require 'thread'
If you still get the error above you can also add `require 'thre...
Inspecting model callback chains
If you need to look at the list of methods that are called upon certain events (like before/after saving etc), do this:
Model._save_callbacks.select {|cb| cb.kind == :before}.map{ |c| c.instance_variable_get :@filter }
Rails 2
User.after_save_callback_chain
To look at the method names only, you could do something like that:
User.after_save_callback_chain.collect(&:method)
Why your previous developer was terrible
When you, as a developer, look at the choices used to build a particular application, you’re blown away at the poor decisions made at every turn. “Why, oh why, is this built with Rails when Node.js would be so much better?” or “how could the previous developer not have forseen that the database would need referential integrity when they chose MongoDB?” But what you may not realize is that you are seeing the application as it exists today. When the previous developer (or team) had to develop it, they had to deal with a LOT of unknowns. They...
Recursively remove unnecessary executable-flags
Sometimes files attain executable-flags that they do not need, e.g. when your Windows VM copies them over a Samba share onto your machine.
From inside your Rails project directory call regularly:
geordi remove-executable-flags
Runs chmod -x
on Ruby, HTML, CSS, image, Rake and similar files.
This script is part of our geordi gem on github.