Search_spinner

Calling selected methods of a module from another module

Given those modules:

module A
  def foo; end
  def bar; end
end

module B
end

When you want to call methods from A inside B you would normally just include A into B:

module B
  include A
end

Including exposes all of A's methods into B. If you do not want this to happen, use Ruby's module_function: it makes a module's method accessible from the outside. You could put the module_function calls into A but it would remain unclear to people…

MySQL: "LOAD DATA INFILE" says "file not found"

This might be due to AppArmor denying the MySQL server access to most of the filesystem. You can instead use

LOAD DATA LOCAL INFILE ...

to pipe data through the MySQL client, which can read everything the executing user can.

Perform HTTP basic authentication in Cucumber (with or without Selenium)

This card describes a Cucumber step that lets you say:

When I perform basic authentication as "username/password" and I visit the admin area

The path component ("… the admin area") is parsed through your path_to helper in features/support/paths.rb.

Capybara

The step definition is part of Spreewald. The step has been tested with multiple versions of Capybara, Rack::Test and Selenium.

Webrat (legacy)

This is a simpler version of the step above:

When /...

Always show the page if there is an error in Cucumber

Are you adding a "Then show me the page" and re-run Cucumber whenever there is a failing scenario? Don't be that guy!

Save time with the shiny new version of our cucumber_spinner gem. It comes with a Cucumber formatter that not only displays an awesome progress bar, and shows failing scenarios immediately, it will also open the current page in your browser whenever a scenario step fails.

After you installed the gem, use the formatter like this:

cucumber --format CucumberSpinner::Curiou...

How to fix "extconf.rb:8:in `require': no such file to load -- mkmf (LoadError)"

If you're on Ubuntu:

sudo apt-get install ruby1.8-dev

On other platforms: Look for a package containing ruby header files. On Red Hat that's "ruby-devel" likely.

Restrict Apache access to your local computer

When you are using Apache for development, it still accepts connections from everyone in the same network as you.

In order to only allow requests to your Apache coming from your local computer, edit your /etc/apache2/ports.conf so all Listen directives point to 127.0.0.1:

Listen 127.0.0.1:80
<IfModule mod_ssl.c>
    Listen 127.0.0.1:443
</IfModule>

After the change stop and start your Apache and check with netstat that Apache no longer listens to 0.0.0.0:

sudo /etc/init.d/apache2 stop
sudo /etc/init.d/ap...

Split an array into groups

Given group size

If you would like to split a Ruby array into pairs of two, you can use the Rails ActiveSupport method in_groups_of:

>> [1, 2, 3, 4].in_groups_of(2)
=> [[1, 2], [3, 4]]

>> [1, 2, 3, 4, 5].in_groups_of(2)
=> [[1, 2], [3, 4], [5, nil]]

>> [1, 2, 3, 4, 5].in_groups_of(2, 'abc')
=> [[1, 2], [3, 4], [5, 'abc']]

>> [1, 2, 3, 4, 5].in_groups_of(2, false)
=> [[1, 2], [3, 4], [5]]

Given group cou…

Properly sanitizing column names for MySQL

There are times when you need to send SQL to the database, like this:

def self.some_count(field)
  field = connection.quote_column_name(field)
  scoped(:select => "COUNT(DISTINCT #{field}) AS count")
end

Although the given variable is sanitized here, the MySQLAdapter's (and probably other adapters as well) method for this is insufficient as it only wraps backticks around it, not helping against injection:

Klass.some_count("id`); DELETE FROM users; -- ")
# Will result in this SQL which is valid but definitely undesira...

Access the documentation of all locally installed gems

Simply run

gem server

and connect to <http://localhost:8808/>.

There you can access the rdoc of all gems installed on your machine. The main page features a useful jump list on top.

In-depth HTTP traffic analysis using tcpdump & Wireshark

From time to time we're convinced that an error must be very close to the network card, OS IP stack or compiler. In reality this is quite rare, so before continuing, triple-check that the issue is not located between chair and keyboard…

If you're still convinced that a in-depth analysis of network traffic might help you, go on:

  • Find out the IP address the client causing trouble will come from.
  • Replace 147.0.0.123 with the client address, log into your web server and run:

    `remote$ sudo tcpdump host 147.0.0.123 and port 80 -s 0 -w…

Setting up Tomcat to use an existing OpenSSL certificate

This is for those who already own an SSL certificate (e.g. using it in the Apache HTTP Server) and need to feed it to a Tomcat application. The main issue is that you need to convert your OpenSSL certificate for Java to use it in its keystore.

Create a keystore

This is the place where the application usually gets its keys from. The keytool is able to read certificate files but does not understand private key files which you need to use y…

Styling and scaling for mobile devices

If you want your application to display properly on iPad, iPhone or Android there are two things to do:

1. Define a stylesheet for mobile devices

Using the media attribute on stylesheet HTML tags allows you to have a CSS for mobile browsers:

<!--[if !IE]><!-->
  <%= stylesheet_link_tag 'mobile', :media => 'only screen and (max-device-width: 1024px)' %>
<!--<![endif]-->

Here I chose 1024 pixels as the maximum device width to include the iPad. If you want to target only mobile p…

Freeze (vendor, unpack) a single Ruby gem with and without Bundler

When you need to patch an existing gem, one way is to "vendor" the gem by copying it into the vendor/gems directory of your Rails project. You can then make any changes you require and Rails will use the vendored version of the gem after a server restart. Unfortunately you need to perform some additional steps to marry Rails and the copied gem. This notes describes what to do.

With Bundler

This is super-painful. If you just copy the gem to vendor/gems, Rails will complain:

Unpacked gem foolib in vendor/gems has no s...

Test the status code of a response in Cucumber

Webrat

Then /^I should get a response with status (\d+)$/ do |status|
  response.status.should include(status)
end

Capybara

Then /^I should get a response with status (\d+)$/ do |status|
  page.status_code.should include(status.to_i)
end
External content

ETags with memcached

I love ETags, but there’s something that annoys me: most implementations revolve around pulling a record out of a data store and only “rendering” the response if it hasn’t been modified. 

The problem with this approach is that request has already gone through most of your application stack–parsing params, authentication, authorization, a few database lookups–so ETags are only saving you render time and some bandwidth.

While working on a Sinatra-based JSON web service that gets very heavy traffic, I wanted to find a way to short-circuit…

Allow a user to run a single command with root privileges

It's that simple to allow one of your Linux users to run a single command as UID 0:

  1. sudo visudo
  2. Add the line below to allow user 'deploy' to run /usr/bin/bundle with root privileges
deploy  ALL=NOPASSWD: /usr/bin/bundle

Don't mix Array#join and String#html_safe

You cannot use Array#join on an array of strings where some strings are html_safe and others are not. The result will be an unsafe string and will thus be escaped when rendered in a view:

unsafe_string = '<span>foo</span>'
safe_string = '<span>bar</span>'.html_safe
[safe_string, unsafe_string].join(' ') # will incorrectly render as '&lt;span&gt;foo&lt;/span&gt;&lt;span&t;bar&lt;/span&gt;'

The solution is not to call html_safe on the joined array and if you thought it would be, you [don't understand how XSS protection …

Shell script to clean up a project directory

Call cleanup-directory from a project root to remove unused and unnecessary files inside it.


This script is part of our geordi gem on github.

2393 cards