Materialized views with Sequel
Sequel is an awesome ORM such as ActiveRecord. The linked article describes how easily you can implement and use materialized views with postgres as your underlying database.
Jasmine: Testing AJAX calls that manipulate the DOM
Here is a Javascript function reloadUsers()
that fetches a HTML snippet from the server using AJAX and replaces the current .users
container in the DOM:
window.reloadUsers = ->
$.get('/users').then (html) ->
$('.users').html(html)
Testing this simple function poses a number of challenges:
- It only works if there is a
<div class="users">...</div>
container in the current DOM. Obviously the Jasmine spec runner has no such container. - The code requests
/users
and we want to prevent network interaction in our uni...
Getter and setter functions for JavaScript properties
JavaScript objects can have getter and setter functions that are called when a property is read from or written to.
For example, if you'd like an object that has a virtual person.fullName
attribute that dynamically composes person.firstName
and person.lastName
:
var person = {
firstName: 'Guybrush',
lastName: 'Threepwood',
get fullName() {
return this.firstName + " " + this.lastName;
},
set fullName(name) {
var parts = name.split(" ");
this.firstName = parts[0];
this.lastName = parts[1];
}
};
`...
Taking screenshots in Capybara
Capybara-screenshot can automatically save screenshots and the HTML for failed Capybara tests in Cucumber, RSpec or Minitest.
Requires Capybara-Webkit, Selenium or poltergeist for making screenshots. Screenshots are saved into $APPLICATION_ROOT/tmp/capybara
.
Manually saving a page
Additionally you can trigger the same behavior manually from the test using Capybara::Session#save_and_open_page and [...
pgcli - Postgres command line interface
A CLI for working with Postgres databases. Ships with auto-completion and syntax highlighting.
Active Record and PostgreSQL — Ruby on Rails Guides
Rails guide that covers PostgreSQL-specific column types and usages for Active Record.
You should especially keep in mind the special datatypes that PostgreSQL offers. \
Types like json
and array
take away a lot of the pain that you had on MySQL projects.
Example use cases for array
are tags or storing foreign keys (instead of a join model). You can even index them.
CarrierWave: How to remove GIF animation
When accepting GIF images, you will also accept animated GIFs. Resizing them can be a time-consuming task and will block a Rails worker until the image is processed.
Save yourself that trouble, and simply tell ImageMagick to drop any frames but the first one.
Add the following to your uploader class:
process :remove_animation
private
def remove_animation
if content_type == 'image/gif'
manipulate! { |image| image.collapse! }
end
end
You may also define that process
for specific versions only (e.g. only for thum...
AngularJS Performance in Large Applications
A lot of the advice involves less separations of concerns in your code ("don't use $watch", "don't use isolated scopes"), but it's a nice summary of what eats time in Angular.
Note that for the purpose of this article "large" mostly mean "large number of watchers/bindings on a single screen". Angular doesn't automatically become large just because you have a lot of screens.
The Easiest Way to Parse URLs with JavaScript
A very clever hack to parse a structured URL object is to create a <a>
element and set its href
to the URL you want to parse.
You can then query the <a>
element for its components like schema, hostname, port, pathname, query, hash:
var parser = document.createElement('a');
parser.href = 'http://heise.de/bar';
parser.hostname; // => 'heise.de'
pathname = parser.pathname; // => '/bar'
if (pathname[0] != '/')
pathname = '/' + pathname // Fix IE11
One advantag...
How to: Context-dependent word expansion in RubyMine
One of the many useful features of TextMate is autocompletion of words. If I were in TextMate right now, I could write "au[tab]", and it would complete it to "autocompletion". RubyMine can do this, too. When you write a word (e.g. a variable name), just hit ALT + / repeatedly and it will offer all completions for the letters you typed. This action is called Cyclic Expand Word in RubyMine / IntelliJ IDEA.
This feature keeps you from mistyping variable names, saves you keystrokes and speeds up development. ~10 keystrokes to the price ...
Vim: How to write a file you opened without sudo
Have you ever opened a file with vim, edited it and when you wanted to save your changes it told you "Can't open file for writing", because you opened it without sudo
? There's an easy hack to let you write it anyway:
:w !sudo tee %
The linked SO post explains in detail what will happen.
Create a shortcut
If you're already used to the "exit vim, run vim with sudo again (sudo !!
) and save" workflow but can't remember the above command, you may create an easy-to-remember shortcut. Add this snippet to your .vimrc
:
" Al...
How to combine "change", "up", and "down" in a Rails migration
Rails migrations allow you to use a change
method whose calls are automatically inverted for the down path. However, if you need to some path-specific logic (like SQL UPDATE
statements) you can not define up
and down
methods at the same time.
If you were to define define all 3 of them, Rails would only run change
and ignore up
and down
. However, Rails 4+ features a helper method called reversible
:
class MyMigration < ActiveRecord::Migration
def cha...
Using Passenger Standalone for development
For our production servers we use Passenger as a Ruby application server. While it is possible to use Passenger for development as an Apache module, the installation process is not for the faint of heart.
Luckily Passenger also comes as a standalone binary which requires zero configuration.
You can Passenger Standalone as a replacement for Webrick or Thin if you'd like to:
- Use SSL certificates locally
- Get performance behavior that is closer to ...
AngularJS 1 Performance: One-time bindings in expressions
In addition to the {{ myValue }}
two-way binding syntax, since Angular 1.3 there's a one-time binding syntax, prefixing the value or expression with ::
, e.g. {{ ::myValue }}, {{ ::myValue >= 42 }} and {{ ::myExpression(value) | someFilter }}
.
One-time bound expressions get dropped from the list of watchers as soon as they can be resolved. Performance-wise the impact for this small change is huge, since Angular apparently slowes down with too many watchers registered [(Source)](http://www.binpress.com/tutorial/speeding-up-angular-js-wi...
Deterministic ordering of records by created_at timestamp
Creating records in specs can be so fast that two records created instantly after one another might have the same created_at timestamp (especially since those timestamps don't have an indefinitely high resolution). When ordering lists by timestamps, you should therefore always include a final order condition using the primary key of the table.
class Photo < ActiveRecord::Base
scope :by_date, -> { order('created_at DESC, id DESC') }
end
Photo.by_date
Remember to include the id
field in the database index.
Returning an empty ActiveRecord scope
Returning an empty scope can come in handy, e.g. as a default object. In Rails 4 you can achieve this by calling none
on your ActiveRecord model.
MyModel.none # returns an empty ActiveRecord::Relation object
For older Rails versions you can use the attached initializer to get a none
scope.
Tagging in Rails 4 using Postgres Arrays
Usage:
class Document < ActiveRecord::Base
scope :any_tags, -> (tags){ where('tags && ARRAY[?]', tags) }
scope :all_tags, -> (tags){ where('tags @> ARRAY[?]', tags) }
end
Document.create(title: "PostgreSQL", tags: ["pg","rails"])
Document.any_tags('pg')
Document.all_tags(['pg', 'rails'])
Migration:
class CreateDocuments < ActiveRecord::Migration
def change
create_table :documents do |t|
t.string :title
t.string :tags, array: true, default: []
t.timestamps
end
add_index :documents, :ta...
Eager-loading polymorphic associations
To avoid n+1 queries, you want to eager-load associated records if you know you need to access them later on.
The Rails docs say:
Eager loading is supported with polymorphic associations.
This is true, but has some caveats.
Example
Consider the following models:
class Image < ActiveRecord::Base; end
class Video < ActiveRecord::Base; end
class PageVersion < ActiveRecord::Base
belongs_to :primary_medium, polymorphic: true # may be Image or Video
end
class Page < ActiveRecord::Base
belongs_to ...
How Exchange handles multipart/alternative emails
In Rails, you can very easily send emails with HTML and plaintext bodies.
However, if you're trying to debug those using your normal email account, you might be out of luck: For some reason, Exchange servers will simply throw away the plaintext part of your mail, and just save the html part.
Change the existing order of an ActiveRecord scope
Use reorder
to replace an existing order clause with a new expression.
Ubuntu: Fix "An error occurred while installing pg"
If you get an error like this:
An error occurred while installing pg (0.17.1), and Bundler cannot continue.
Make sure thatgem install pg -v '0.17.1'
succeeds before bundling.
Then do this:
sudo apt-get install libpq-dev
... and run Bundler again.
Rspec: Complex argument expectations for should_receive
Sometimes you need complex expectations on method arguments like this
SomeApi.should_receive(:find).with(:query => '*foo*', :sort => 'timestamp ASC', :limit => 100).and_return(['some result'])
This is not very flexible, and failure messages will be hard to read.
Instead, consider doing this:
SomeApi.should_receive(:find) do |params|
params[:query].should == '*foo*'
params[:sort].should == 'timestamp ASC'
params[:limit].should == 100
['some result']
end
What we know about PDFKit
What PDFKit is
- PDFKit converts a web page to a PDF document. It uses a Webkit engine under the hood.
- For you as a web developer this means you can keep using the technology you are familar with and don't need to learn LaTeX. All you need is a pretty print-stylesheet.
How to use it from your Rails application
- You can have PDFKit render a website by simply calling
PDFKit.new('http://google.com').to_file('google.pdf')
. You can then send the...
Alternative for Ruby singletons
require 'net/http'
module Cheat
extend self # the magic ingredient
def host
@host ||= 'http://cheat.errtheblog.com/'
end
def http
@http ||= Net::HTTP.start(URI.parse(host).host)
end
def sheet(name)
http.get("/s/#{name}").body
end
end
# use it
Cheat.sheet 'migrations'
Cheat.sheet 'singletons'