Aggregated RSpec/Cucumber test coverage with RCov
With defaults, RCov doesn't work the way you how you would like it to. To create a nice test coverage report, copy the attached file to lib/tasks/rcov.rake. After that rake rcov:all will run all RSpec examples and Cucumber features. The report will be written RAILS_ROOT/coverage/index.html.
Here is what the task does in detail:
- Generates aggregated coverage of both RSpec and Cucumber
- Works with Rails 2 and Rails 3
- Reports for
app/**/*.rband nothing else - If called with an environment variable
IGNORE_SHARED_TRAITS=trueit ...
Using StaticMatic for static pages
Update: Staticmatic will not be further developed. They suggest to switch to middleman.
If you need to make a static web page and find yourself missing all your Rails comforts, take a look at StaticMatic.
This works like an extremely stripped down version of Rails, giving you
- HAML
- SASS
- helpers
- partials
When done, everything is simply compiled to s...
Alternative to #to_a and Array(...)
Note: In Rails 3+ you can use Array.wrap instead of the solution here.
In the past you could use Array(...) or #to_a to turn an object into an array, unless it already is an array:
Array(5) # => [5]
Array([5]) # => [5]
Unfortunately this idiom has issues and it also triggers deprecation warnings like this one:
warning: default `to_a' will be obsolete
For an alternative you can copy the attached file to `config/i...
Stub methods on any instance of a class in Rspec 1 and Rspec 2
RSpec 1 (Rails 2)
With the most recent spec_candy.rb helpers you can say:
User.stub_any_instance(:foo => :bar)
user = User.new
user.foo
# => :bar
RSpec 2 (Rails 3)
RSpec 2 comes with this feature built in:
User.any_instance.stub(:foo => :bar)
user = User.new
user.foo
# => :bar
RSpec 3
-------...
Email validation regex
There is a practical short list for valid/invalid example email addresses - Thanks to Florian L.! The definition for valid emails (RFC 5322) can be unhandy for some reasons, though.
Since Ruby 2.3, Ruby's URI lib provides a built-in email regex URI::MailTo::EMAIL_REGEXP. That's the best solution to work with.
/\A[a-zA-Z0-9.!\#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[...
How to change the order of nested forms being rendered (especially blank forms)
Generally for nested forms, a blank form is placed below all other existing object forms. If you would like to change the position of the blank form(s) you can reorder the object's one-to-many association. For example you can put the blank form on top with the following snippet:
actors = movie.actors
actors.build
actors.unshift(actors.pop(1)) # won't work with Rails 4+
Because build_for_form creates new objects and ap...
How to inspect controller filter chains in specs
Sometimes you need to look at the filter chain in specs. You can do it like that on Rails 2:
controller.class.filter_chain.map(&:method)
Note that we need to look at the controller's class since before_filter and after_filter stuff happens on the class level.
Also mind that the above code will give you all filters, both those run before and after an action. You can query before? and after? on the filter objects to scope down to only some of them:
controller.class.filter_chain.select(&:before?).map(&:method)
For Rails 3, ...
Unfreeze a frozen ActiveRecord
You can freeze any Ruby object to prevent further modification.
If you freeze an ActiveRecord and try to set an attribute you will an error like this:
can't modify frozen hash
This is because ActiveRecord delegates #freeze to its attributes hash.
You can unfreeze most Ruby objects by creating a shallow copy of the frozen object by calling #dup on it:
user = User.find(3)
user.freeze
unfrozen_user = user.dup
Notes for Rails 2 users
-----------------...
Fix "couldn't parse YAML" error after upgrading Bundler
If you just upgraded to Bundler 10.0.10 you might get the following error when bringing up Rails:
/usr/lib/ruby/1.9.1/psych.rb:148:in `parse': couldn't parse YAML at line 17 column 14 (Psych::SyntaxError)
This is caused by Rails localization files (en.yml, de.yml, etc.) using symbols for various translation strings, and Bundler 10.0.10 defaults to a new YAML engine which cannot handle symbols.
You can switch back to the old YAML engine by ...
How to render an html_safe string escaped
Once Rails knows a given string is html_safe, it will never escape it. However, there may be times when you still need to escape it. Examples are some safe HTML that you pipe through JSON, or the display of an otherwise safe embed snippet.
There is no semantically nice way to do this, as even raw and h do not escape html_safe strings (the former just marks its argument as html_safe). You need to turn your string into an unsafe string to get the escaping love from Rails:
embed = javascript_tag('var foo = 1337;') # This is an h...
include_tags with the asset pipeline
You can include files from app/assets or from the public folder with javascript_include_tag. The subtle difference that tells rails how to build the path correctly is a single slash at the beginning of the path:
<%= javascript_include_tag('ckeditor/config') %> # for assets/ckeditor/config.js
<%= javascript_include_tag('/ckeditor/ckeditor') %> # for public/ckeditor/ckeditor.js
This also applies to stylesheet_link_tag.
Note that when you refer to a Javascript or stylesheet in /assets you need to add it to [the list of asse...
Run specific version of bundler
You can specify the version of bundler to execute a command (most often you need an older version of bundler, but don't want to uninstall newer ones):
bundle _1.0.10_ -v
Bundler version 1.0.10
An example is rails 3.2, which freezes bundler at version ~> 1.0:
Bundler could not find compatible versions for gem "bundler":
In Gemfile: rails (~> 3.2) was resolved to 3.2.0, which depends on bundler (~> 1.0)
Current Bundler version: bundler (1.13.6)
You can solve this with:
gem install bundler -v 1....
HTML5: Allow to choose multiple files with a vanilla file picker
Modern browsers natively suppport file pickers that allow the user to choose multiple files at once. To activate this feature, set the multiple attribute:
<input type="file" name="images[]" multiple />
Or in a Rails view:
<%= file_field_tag "images[]", multiple: true %>
This works in IE10+.
Make sure that the field name ends in [] so your server-side code will parse the incoming files into an array. Obviously this naming convention is not compatible with default Rails nested attribute setters, so you'll need to write a form ...
simple_format helper for Javascript
The Javascript code below is a rough equivalent to the simple_format helper that ships with Rails:
function simpleFormat(str) {
str = str.replace(/\r\n?/, "\n");
str = $.trim(str);
if (str.length > 0) {
str = str.replace(/\n\n+/g, '</p><p>');
str = str.replace(/\n/g, '<br />');
str = '<p>' + str + '</p>';
}
return str;
}
Unlike the Rails helper, this does not preserve whitespace. You probably don't care.
Minified JavaScript and CSS
JavaScripts and CSS should be minified for production use.
In Rails 3.1+ the asset pipeline will take care of this. Thus you're best off using an uncompressed version of your Javascript in development. Also load the non-minified versions of libraries. This way debugging will be easier and you will still get all the minification love once deployed.
In Rails 2.3 and 3.0 you should at least embed external JavaScript libraries in minified form, using something like JavaScript compressor.
Fix Rubygems warning: Gem.source_index is deprecated, use Specification
After updating Rubygems you see a wall of deprecation warnings like this:
NOTE: Gem::SourceIndex#add_spec is deprecated, use Specification.add_spec. It will be removed on or after 2011-11-01.
Gem::SourceIndex#add_spec called from /usr/local/lib/site_ruby/1.8/rubygems/source_index.rb:197.
NOTE: Gem::SourceIndex#add_specs is deprecated with no replacement. It will be removed on or after 2011-11-01.
Gem::SourceIndex#spec_dirs= called from /usr/lib/ruby/gems/1.8/gems/bundler-1.0.14/lib/bundler/rubygems_integration.rb:175
...
Ruby 2.3.0 has a safe navigation operator
As announced before, Ruby has introduced a safe navigation operator with version 2.3.0. receiver&.method prevents NoMethodErrors by intercepting method invocations on nil.
user = User.last
user&.name # => "Dominik"
# When there is no user, i.e. user is nil:
user&.name # => nil
This might remind you of andand, and indeed it behaves very similar. The only difference is in handling of `fa...
Bash: How to use colors in your tail output
Sometimes it's nice to have some coloring in your logs for better readability. You can output your logs via tail and pipe this through sed to add ANSI color annotations (which your console then interprets).
To print a log (e.g. rails log) and color all lines containing "FATAL" in red and all lines with "INFO" in green:
tail -f /path/to/log | sed --unbuffered -e 's/\(.*INFO.*\)/\o033[32m\1\o033[39m/' -e 's/\(.*FATAL.*\)/\o033[31m\1\o033[39m/'
Here are the ...
Define a route that only responds to a specific format
You won't usually have to do this. It's OK to route all formats to a controller, and let the controller decide to which format it wants to respond.
Should you for some reason want to define a route that only responds to a given format, here is how you do it:
Rails 3
match 'sitemap.xml' => 'feeds#sitemap', :constraints => { :format => 'xml' }, :as => 'sitemap'
Rails 2
map.sitemap 'sitemap.xml', :controller => 'feeds', :action => 'sitemap', :format => 'xml'
Katapult 0.3.0 released
Katapult 0.3.0 brings Rails 5 and Ruby 2.5 support with a new design, plus a ton of smaller features, fixes and improvements.
Features
- Generating a Rails 5.1.4 app on Ruby 2.5.0
- Dropped asset pipeline in favor of Webpacker
- The generated application now has a sleek, simple design based on Bootstrap
- Employing Unpoly
- New application model DSL shortcut
crudfor "create a model and a web UI with crud actions" - The generated application model is now a transformable e...
Understanding database cleaning strategies in tests
TLDR: In tests you need to clean out the database before each example. Use :transaction where possible. Use :deletion for Selenium features or when you have a lot of MyISAM tables.
Understanding database cleaning
You want to clean out your test database after each test, so the next test can start from a blank database. To do so you have three options:
- Wrap each test in a transaction which is rolled back when you're done (through
DatabaseCleaner.strategy = :transactionor `config.use_transactional_fi...
ActiveRecord 3+ auto-converts times to UTC by default. Hilarity ensues.
Remember how Rails 2 came with an awesome feature that broke all code using Time.now or Time.parse?
This behavior is now the default for Rails 3. Disable it by adding the following to your config/application.rb:
config.active_record.default_timezone = :local
config.active_record.time_zone_aware_attributes = false
ActiveRecord meets database views with scenic
Using Scenic, you can bring the power of SQL views to your Rails application without having to switch your schema format to SQL. Scenic provides a convention for versioning views that keeps your migration history consistent and reversible and avoids having to duplicate SQL strings across migrations. As an added bonus, you define the structure of your view in a SQL file, meaning you get full SQL syntax highlighting in the editor of your choice and can easily test your SQL in the database console during development.
[https://robots.thoughtb...