Setting nil values in Machinist blueprints
Take care when trying to set attributes to nil
in a blueprint.
Given the following master blueprint:
Story.blueprint do
title
author { User.make }
editor { User.make }
end
This approach will not overwrite/remove the editor
defined in the master blueprint:
Story.blueprint(:draft) do
editor nil
end
...whereas this one will (note the lambda):
Story.blueprint(:draft) do
editor { nil }
end
Dealing with ActiveRecord::RecordNotSaved
If you get an ActiveRecord::RecordNotSaved
error, a method inside one of your model's callback chains (before_save
etc) possibly returned false.
This commonly happens when you have a method setting attributes and the last one is a boolean set to false (as the value of the last statement is returned). Fix this by simply calling true
at the end of such methods:
def hide
self.visible = false
true
end
Note that nil
won't cause this behavior. Thus, you can use an if
without problems -- if you are not returning fal...
Here’s what we’ve learned about doing UI for mobile web apps with WebKit
Lately, we’ve been exploring ways to offer web apps that perform like native apps on mobile devices. For this short sprint we targeted mobile WebKit browsers—especially the default browsers on iOS and Android—because of their widespread use and excellent support for HTML5 and CSS3. Here are a few things we’ve learned along the way.
Match strings in a given order with Cucumber and Capybara
Sometimes the order in which strings appear on a page matters to you.
Spreewald gives you steps like these:
Then I should see in this order:
| Alpha Group |
| Augsburg |
| Berlin |
| Beta Group |
Or, if you prefer multiline strings:
Then I should see in this order:
"""
Alpha Group
Augsburg
Berlin
Beta Group
"""
The step ignores all HTML tags and only tests on plain text.
Preload tags with acts-as-taggable-on
When you do tags with acts-as-taggable-on and want to preload associated tags, you can do so with
TaggedModel.scoped(:include => :tag)
Note however that this will only prevent tagged_model.tags
from hitting the database. Using tagged_model.tag_list
does not use the preloaded association.
Solve ActiveRecord::MissingAttributeError "missing attribute: foo"
Did you use the :select
option in a find
, and forgot to include foo
?
Machinist: Refer to another named blueprint inside a blueprint
Note: We are talking about Machinist 1 here, Machinist 2 may have solved this or might require a different approach.
Machinist allows named blueprints (e.g. User.blueprint(:admin)
) that inherit from the master blueprint (User.blueprint
).
If you also want to inherit from another blueprint (e.g. if "vip" should load "premium" and the master blueprint) you can do this:
User.blueprint(:vip) do
# Fields for the vip blueprint go her...
Be careful with Array(...)
A popular ruby idiom I keep stumbling upon is
def do_some_thing_for(values)
values = Array(values)
values.each { ... }
end
The intent is to allow the user to pass in arrays as well as scalar values, since
Array("foo") == ["foo"]
Array(["foo", "bar"]) == ["foo", "bar"]
But Array()
actually calls to_a
on its arguments, which may not always do what you expect. For example
Array("foo \n bar") == ["foo \n", "bar"]
Deliver Paperclip attachments to authorized users only
When Paperclip attachments should only be downloadable for selected users, there are three ways to go.
The same applies to files in Carrierwave.
- Deliver attachments through Rails
The first way is to store Paperclip attachments not in the default public/system
, but in a private path like storage
inside the current release. You should prefer this method when dealing with sensitive data.
Make ...
Install the Nokogiri gem on Ubuntu servers
You need to install the following packages before you can build the Nokogiri gem:
sudo apt-get install libxml2-dev libxslt1-dev
Resolve Aspell errors with your Rails application
If you get an error message like that you are missing the Aspell files a specific language:
No word lists can be found for the language "de"
Solve it by installing the proper package, e.g. on Ubuntu:
sudo apt-get install aspell-de
Prevent SSH from timing out
If you have problems with SSH session timing out, add the following to your /etc/.ssh/config
:
Host *
ServerAliveInterval 55
ServerAliveCountMax 2
Using the full power of have_css
Capybara's has_css?
matcher has a couple of options you might find useful.
Check that a selector appears a given number of times
Use the :count
option like this:
Then /^I should see (\d+) users?$/ do |count|
page.should have_css('ul#users li', :count => count.to_i)
end
Check that a selector has a given text content
Use the :text
option like this:
Then /^I should see a user with name "([^\"]*)"$/ do |nam...
apotonick's hooks at master - GitHub
Hooks lets you define hooks declaratively in your ruby class. You can add callbacks to your hook, which will be run as soon as you run the hook.
Even with bundler your gem order can be significant
Even when you're using bundler, it might be significant in which order your gems are listed in your Gemfile
. This can happen when gems are running around calling require
or require_dependency
on other gems or application classes when loaded (don't do that!).
A known culprit of this is the (otherwise wonderful) resource_controller gem, which requires ApplicationController
when loaded. When your ApplicationController
requires later-loaded gems when loaded, Rails will not boot.
He...
An obscure kernel feature to get more info about dying processes
This post will describe how I stumbled upon a code path in the Linux kernel which allows external programs to be launched when a core dump is about to happen. I provide a link to a short and ugly Ruby script which captures a faulting process, runs gdb to get a backtrace (and other information), captures the core dump, and then generates a notification email.
Inline if-then-else in MySQL queries
It can be useful to have a Ruby expression like condition ? positive_case : negative_case
in MySQL queries:
UPDATE users SET monthly_debit = IF(subscriber, 19, 0)
Precedence of Ruby operators
[ ] [ ]=
**
! ~ + -
* / %
+ -
>> <<
&
^ |
<= < > >=
<=> == === != =~ !~
&&
||
.. ...
? :
= %= { /= -= += |= &= >>= <<= *= &&= ||= **=
defined?
not
or and
if unless while until
begin/end
For more information see Table 18.4 in The Pragmatic Programmer's Guide.
Generate a strong secret from the shell
A good tool to generate strong passwords and secrets is "apg". You can get it with
sudo apt-get install apg
To create a strong secret for sessions, hashed Paperclip paths, etc. say
apg -m128 -a1 -E\'\"
Arguments explained:
- The
-m
parameter defines the secret length -
-a1
makes apg choose from all 7-bit ASCII characters instead of just the alphabet -
-E\'\"
excludes quote characters so you can easily paste the secret into a Ru...
Taking advantage of RSpec's "let" in before blocks
Inside before
:each
blocks you can refer to variables that you introduce via let
later on.
They do not need to be defined ahead of your before block and can be different for individual sections.
It works just like that:
describe User do
describe '#locked?' do
before :each do
subject.should_receive(:current_plan).and_return plan
end
context 'when expiring today' do
let(:plan) { stub(:expiry => Date.today) }
it 'should be false' do
subject....
jsmestad's pivotal-tracker at master - GitHub
Ruby gem that provides an AR-style interface for the Pivotal Tracker API.
Install the Paperclip gem on Ubuntu servers
You need to install the following packages before you can build the Paperclip gem:
sudo apt-get install imagemagick librmagick-ruby
Pay attention to the order of your submit buttons
If you have several submit elements (input
s or button
s with type="submit"
) that each cause different things to happen (e.g. you might have a button that sends an extra attribute) you might run into trouble when submitting the form by pressing the return key in a field.
When nothing fancy like a tabindex
is defined it seems as if the first submit element inside a form is chosen (and has its attributes submitted) when pressing return.\
So, if possible, put your "default" (aka least harmful) submit element before others.
NB: If you s...