When the iPad won't play an MP4 video
I had trouble serving an MP4 video to my iPad. Although the video complied with all the specs (H.264 codec, up to 1080p, 30 FPS) I always got this error:
This video could not be loaded, either because the server or network failed or because the format is not supported: http://10.40.0.177:3000/video.mp4
After spending a lot of time fighting this issue, I tried to upload the same unchanged video file to a production server (Apache / Passenger). It worked immediately. I guess iOS is picky about some HTTP header that my local HTTP server (Th...
Plotting graphs in Ruby with Gruff
Geoffrey Grosenbach has created Gruff for easily plotting graphs. It is written in pure Ruby and integrates with Rails applications.
It provides features as automatic sizing of dots and lines (the more values, the thinner the graph's elements), custom or predefined themes, different styles (bar, line, dot and many more) and multiple graphs in one chart.
Installation
In your Gemfile:
gem 'rmagick', :require => false
gem 'gruff'
Then run bundle install
(and don't forget to restart your development server.)
Usage
This i...
Guide to localizing a Rails application
Localizing a non-trivial application can be a huge undertaking. This card will give you an overview over the many components that are affected.
When you are asked to give an estimate for the effort involved, go through the list below and check which points are covered by your requirements. Work with a developer who has done a full-app localization before and assign an hour estimate to each of these points.
Static text
- Static strings and template text in
app
must be translated: Screens, mailer templates, PDF templates, helpe...
RubyMine: Set specific Ruby version per project
If your project uses another version than your default Ruby, RubyMine will give you incorrect inspections, for example.\
Here is how to switch which Ruby you use in RubyMine.
- File → Settings (Or press
Ctrl+Alt+S
) - Select "Ruby SDK and Gems" from the left pane
- Switch your "Ruby interpreter".
Though it may seem you are changing a global setting here, this is in fact a per-project setting, as are all things you change in the "Project Settings [your_project_name]" area of the global settings dialog.
When you switch to another proje...
Compress bitmap images within PDF files
Embedding bitmap images within PDF sometimes results in large files because the bitmaps are not compressed. If you don't need high quality images within the resulting PDF file, you can use ghostscript to compress embedded images:
ghostscript -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH -sOutputFile=new-smaller-file.pdf large-original-file.pdf
Note that your PDF printer (or similiar generation tools) also often come with a compression setting for embedded raster images.
You can put this ...
Sync confidential files between unixes using cloud storage and encfs
Note: You might also want to check out BoxCryptor which does pretty much the same, and is supported across many more platforms. I just didn't want to use Dropbox...
I use Ubuntu One to automatically sync confidential files between my machines. The encryption is done via encfs, which is a file-based encryption that simply puts encrypted versions of files from one folder into another. This is well-suited for cloud storage, since it allows syncing single files, not whole crypt containers.
Recipe
I'll ass...
Bundle capistrano
Capistrano recently had some API changes that can results in deploys not working when running with old deploy.rb
files.
So let's bundle it. Put capistrano into your Gemfile, like this:
# Gemfile
group :deploy do
gem 'capistrano'
gem 'capistrano_colors'
end
It's possible you need to do a bundle update net-ssh
to get things running.
Now double check that all your custom hooks are actually still called. One candidate might be an after deploy:symlink
hook that has been renamed into `after deploy:creat...
How to use pessimistic row locks with ActiveRecord
When requests arrive at the application servers simultaneously, weird things can happen. Sometimes, this can also happen if a user double-clicks on a button, for example.
This often leads to problems, as two object instances are modified in parallel maybe by different code and one of the requests writes the results to the database.
In case you want to make sure that only one of the requests "wins", i.e. one of the requests is fully executed and completed while the other one at least has to wait for the first request to be completed, you ha...
Aspect Oriented Programming in Ruby
Slides presenting ways to integrate the ideas of Aspect-Oriented Programming in Ruby.
Outline
- Why Aspect-Oriented Programming?
- AOP in Java and AspectJ (a Review).
- AOP in Ruby.
- What you can do today.
- Example AOP-isms in Ruby on Rails.
- Aspect-Oriented Design.
- The AOP Promise for Tomorrow.
You cannot use :before or :after on img in CSS
Though the W3C even gives it as an example, no browser actually supports this CSS:
img:before {
content: "something";
}
Browsers will simply not render anything when doing that on images (Fun fact: It worked in an older version of Opera but got dropped).\
The same applies to the :after
pseudo-element.
This makes me sad.
You can try using jQuery instead.
Use a special version of Chrome for selenium (and another for your everyday work)
Sometimes you need a special version of chrome because it has some features you need for testing, like in this card. You do not need to use that Version apart from tests, because you can tweek selenium to use a special version that you set in your environment:
# features/support/chrome.rb
require "selenium/webdriver"
Capybara.register_driver :chrome320x480 do |app|
if driver_path = ENV["CHROME_SELENIUM_BIN...
Set the accept-language of Chrome in selenium tests
You can set the resolution and user agent used in selenium tests with chrome with the method described in this card, but you can also set the accept-language and other profile settings if you do this:
# features/support/chrome.rb
require "selenium/webdriver"
Capybara.register_driver :chrome320x480 do |app|
args = []
args << "--window-...
Run Chrome in a specific resolution or user agent with Selenium
When you want to test how an web-application reacts in a specific resolution, you can set up a specific Selenium driver for some tests:
Before('@chrome320x480') do
Capybara.current_driver = :chrome320x480
end
After('@chrome320x480') do
Capybara.use_default_driver
end
You can use either chromium or chrome beta (as of 2012.05 the Version "19.0.1084.41 beta" works), or any other member of the family. It only needs to supports the "--window-size" command-line switch. [See this list](http://peter.sh...
How to access a dmcrypt-encrypted partition from outside your system
This is for you when you want to mount a dmcrypt
encrypted partition manually, e.g. from a live CD.
First, open the dmcrypted partition (You need to provide some name. It may, but does not need to, be your LVM group name):
cryptsetup luksOpen /dev/sda5 some_name
Since your encryption container most likely contains an LVM group (root + swap for example), enable the logical volume manager (replace LVM_NAME
with your volume group's name):
vgchange -ay LVM_NAME
After that, you can your access (mount, [fsck](https://makandrac...
Authorize allowed values with assignable_values
All our projects have enum-like requirements like this:
- An attribute value must be included in a given set of values.
- The list of allowed values must be retrievable in order to render
<select>
boxes. - Each value has a humanized label.
- Sometimes there is a default value.
Most of the time, this requirement is also needed:
- The list of assignable values depends on the user who is currently signed in.
In our past projects there are many different solutions for these related requirements, e.g. ChoiceTrait
, methods like `available_...
Google Analytics: Changing the tracked URL path
By default, Google Analytics tracks the current URL for every request. Sometimes you will want to track another URL instead, for example:
- When an application URL contains a secret (e.g. an access token)
- When you want to track multiple URLs under the same bucket
- When you want to track interactions that don't have a corresponding URL + request (e.g. a Javascript button or a PDF download)
Luckily the Analytics code snippet allows you to freely choose what path is being tracked. Simple change this:
ga('send', 'pageview');
......
Why has_many :through associations can return the same record multiple times
An association defined with has_many :through
will return the same record multiple times if multiple join models for the same record exist (a n:m relation). To prevent this, you need to add ->{ uniq }
as second argument to has_many
(below Rails 4 it is a simple option: has_many :xyz, :uniq => true
).
Example
Say you have an Invoice
with multiple Items
. Each Item
has a Product
:
class Invoice < ActiveRecord::Base
has_many :items
has_many :products, :through => :items
end
class Item < ActiveRecord::Base
...
Issue with an escaped "equals" sign in the development log email representation
An =
is represented by =3D
in the log file.
I got confused by the leading 3D
which is not part of the token, you can see in the following example:
Hallo Max!
Danke f=C3=BCr deinen Beitrag. Bitte best=C3=A4tige deine Teilnahme, inde=
m du auf den folgenden Link klickst:
http://localhost:3000/beitraege/13/confirm?token=3DEA7BB9DA73FF17AO
Viele Gr=C3=BC=C3=9Fe vom Team!
My token is actually only EA7BB9DA73FF17AO
.
Fix warning: Cucumber-rails required outside of env.rb
After installing Bundler 1.1 you will get the following warning when running tests:
WARNING: Cucumber-rails required outside of env.rb. The rest of loading is being defered until env.rb is called.\
To avoid this warning, move 'gem cucumber-rails' under only group :test in your Gemfile
The warning is misleading because it has nothing to do with moving cucumber-rails
into a :test
group. Instead you need to change your Gemfile
to say:
gem 'cucumber-rails', :require => false
Ruby blocks: Braces and do/end have different precedence
TL;DR {}
binds stronger than do … end
(as always in Ruby, special characters bind stronger than words)
Demo
✔️ Right way
names = ['bRUce', 'STaN', 'JOlIE']
# Blocks in braces are passed to the rightmost method
print names.map { |name| name.downcase }
print(names.map do |name| name.downcase end) # equivalent
=> ["bruce", "stan", "jolie"]
❌ Wrong way
Avoid the examples below, as you pass at least one block to print and not to the enumerator.
names = ['bRUce', 'STaN', 'JOlIE']
# Blocks in do…end ar...
MySQL shell: Vertical vs horizontal layout
When talking to your MySQL server via a mysql
shell, you can terminate queries by ;
or \G
-- the latter gives you a vertical output.
You know this:
mysql> SELECT * FROM users;
+----+---------+---------------------+-----------------+
| id | name | email | greeting |
+----+---------+---------------------+-----------------+
| 1 | Alice | alice@example.com | Hello world! |
| 2 | Bob | bob@example.com | Hello universe! |
| 3 | Charlie | charlie@example.com | Hi mom! ...
Ruby: Making your regular expressions more readable with /x and alternative delimiters
The following two hints are taken from Github's Ruby style guide:
If your regular expression mentions a lot of forward slashes, you can use the alternative delimiters %r(...)
, %r[...]
or %r{...}
instead of /.../
.
%r(/blog/2011/(.*))
%r{/blog/2011/(.*)}
%r[/blog/2011/(.*)]
If your regular expression is growing complex, you can use the /x
modifier to ignore whitespace and comments:
regexp = %r{
start # some text
\s # white space char
(group) ...
Show MySQL process list without sleeping connections
Usually you don't need to, but when you want to see which queries your MySQL server currently needs to handle (and if there are locks, etc), you could say SHOW PROCESSLIST
in a MySQL shell.
Unfortunately, SHOW PROCESSLIST
does not allow filtering. When you are on MySQL ≥ 5.1.7, do this instead:
SELECT * FROM information_schema.processlist WHERE command != 'Sleep' ORDER BY id;
That also allows you to only show some values or order differently, like so:
SELECT user, time, state, info FROM information_schema.processlist WHERE co...
Change how Capybara sees or ignores hidden elements
Short version
- Capybara has a global option (
Capybara.ignore_hidden_elements
) that determines whether Capybara sees or ignores hidden elements. - Prefer not to change this global option, and use the
:visible
option when callingpage.find(...)
. This way the behavior is only changed for this onefind
and your step doesn't have confusing side effects. - Every Capybara driver has its own notion of "visibility".
Long version
Capybara has an option (Capybara.ignore_hidden_elements
) to configure the default...