ActiveRecord 2.3: Nested attribute changes disappear

There is a bug in ActiveRecord 2.3.x that leads to changes in nested forms getting lost.

class Project < ActiveRecord::Base
  has_many :tasks
  accepts_nested_attributes_for :tasks
end

If you access project.tasks after setting tasks through the nested attribute logic, all tasks will be reloaded and all changes will be lost. This usually happens

  • in validations
  • in callbacks
  • after validation errors, when rendering the view again

The attached initializer fixes those issues.

Prevent double clicks on link_to_remote (simple case)

This works well in the simplified case, when your link disappears after it was clicked.

Let link_to_remote behave as „disabled“ after the first click. Use the :before hook to replace the orignal link with a link that does nothing but looks like the original link:

:ruby
  label = "do_something"
  dummy_link = link_to(label)
  other_attributes_hash = { :url => ..., :method => ..., ... }
  
  disable_link_option = { :before => "$('your_link_selector').html('#{escape_javascript(dummy_link)}'" } # jquery

= link_to_remote(label, other_att...

Test that a form field is visible with Cucumber/Capybara

Spreewald now comes with a step that tests if a form field is visible:

Then the "Due date" field should be visible
But the "Author" field should not be visible

The step works by looking up the field for the given label, then checks if that field is hidden via CSS (or Javascript).

It is not currently tested if the label is visible or hidden. For this see: [Check that an element is visible or hidden via CSS with Cucumber/Capybara](https://makandracards.com/makandra/1049-check-that-an-elem...

Consul: Dynamically access and query powers for a given name, model class or record

Consul 0.6.1+ gives you a way to dynamically access and query powers for a given name, model class or record.
A common use case for this are generic helper methods, e.g. a method to display an "edit" link for any given record
if the user is authorized to change that record:

module CrudHelper

  def edit_record_action(record)
    if current_power.include_record?(:updatable, record)
      link_to 'Edit', [:edit, record]
    end
  end

end

You can find a full list of available dynamic calls bel...

Understanding race conditions with duplicate unique keys in Rails

validates_uniqueness_of is not sufficient to ensure the uniqueness of a value. The reason for this is that in production, multiple worker processes can cause race conditions:

  1. Two concurrent requests try to create a user with the same name (and we want user names to be unique)
  2. The requests are accepted on the server by two worker processes who will now process them in parallel
  3. Both requests scan the users table and see that the name is available
  4. Both requests pass validation and create a user with the seemingly available name...

Using Apache Benchmark (ab) on sites with authentication

Apache HTTP server benchmarking tool (ab) is a nice tool to test performance on sites delivered by HTTP. If the site you're about to test is placed behind a login, follow these steps to successfully use ab on it.

  1. Open the site to test in the browser of your choice. Do not login yet.
  2. Use developer tools to show all cookies used by the site. (Chrome: Ctrl+Shift+i, open the 'Resources' tab and click on the site below 'Cookies' on the left. Firefox: Right-click on the site, open 'We...

Detect effective horizontal pixel width on a mobile device with Javascript

So you want to find out how many horizontal pixels you have available on a mobile device. This is super difficult because:

Rails 4 Countdown to 2013 | The Remarkable Labs Blog

With the impending release of Ruby on Rails 4, it looks like a lot of developers will be updating their web applications in the coming new year.

To help with this transition, over the next 31 days, we are going to be releasing a series of blog posts going over everything you will need to know about Rails 4 for an effortless upgrade.

The Shapes of CSS

Examples how to create dozens of shapes using pure CSS and a single HTML element.

RSpec: Defining helper methods for an example group

You can define methods in any example group using Ruby's def keyword or define_method method:

describe "example" do
  def sum(a, b)
    a + b
  end

  it "has access to methods defined in its group" do
    expect(sum(3, 4)).to be(7)
  end
end

The helper method is also available to groups nested within that group. The helper method is not available to parent or sibling groups.

Global helpers

To define helpers for all specs (or all specs of a type), [define it in a module](https://rspec.info/features/3-12/rspec-core/help...

Everything you ever wanted to know about constant lookup in Ruby

If you ever wondered why a constant wasn't defined or wasn't available where you expected it to be, this article will help.

Also see Ruby constant lookup: The good, the bad and the ugly.

jquery-timing - a jQuery plugin you should know about

jquery-timing is a very useful jquery plugin that helps to remove lots of nested anonymous functions. It's API provides you some methods that help you to write readable and understandable method chains. See yourself:

Example

// before
$('.some').show().children().doThat();
window.setTimeout(function(){
  $('some').children().doSomething().hide(function() {
    window.setTimeout(function() {
      otherStuffToDo();
    }, 1000);
  });
}, 500);

// after
$('.some').s...

How to provoke Selenium focus issues in parallel test processes

As attachments to this card you will find a Cucumber feature and supplementing step definition that you can use to provoke Selenium focus issues that only occur when two focus-sensitive Selenium scenarios run at the same time (probably with parallel_tests). This can help you to detect and fix flickering integration tests.

The attached feature works by going to your root_path and focusing a random form element every 5...

How to find out the currently focused DOM element with JavaScript

This works in all relevant browsers:

document.activeElement

You can use this in your Selenium steps, for example, to assert that a form field is or is not focused.

Performance analysis of MySQL's FULLTEXT indexes and LIKE queries for full text search

When searching for text in a MySQL table, you have two choices:

  • The LIKE operator
  • FULLTEXT indexes (which currently only work on MyISAM tables, but will one day work on InnoDB tables. The workaround right now is to extract your search text to a separate MyISAM table, so your main table can remain InnoDB.)

I always wondered how those two methods would scale as the number of records incr...

Custom error pages in Rails

Static error pages

To add a few basic styles to the default error pages in Rails, just edit the default templates in public, e.g. public/404.html.

A limitation to these default templates is that they're just static files. You cannot use Haml, Rails helpers or your application layout here. If you need Rails to render your error pages, you need the approach below.

Dynamic error pages

  1. Register your own app as the applicatio...

Render Sass stylesheets dynamically

If - for whatever reason - you have to render stylesheets dynamically, the following snippet might be of help. It emulates what "sprockets" would to when precompiling your assets, and give your stylesheets access to all the regular bells and whistles (like asset_path, proper @imports etc):

class DynamicStylesheetsController < ApplicationController

    def show
      logical_path = RELATIVE_PATH_TO_YOUR_TEMPLATE
      path = File.join(Rails.root, logical_path)
      template = Sass::Rails::SassTemplate.new(path)
      environment = ...

Git: Improve your commits by reviewing changes one-by-one

Git commits should be very deliberate, and only contain changes that you really want to be in there. In order to reduce the chance to accidentally commit something you didn't intend, review your changes before committing.

My preferred way of doing this is (only using git)

git add -N . # Add all paths, but not their contents
git add -p

Git will now show you all your changes in small chunks and ask you in an interactive mode whether you really want to add them.

The most helpful commands are

  • y: yes (add the change)
  • ...

Debugging Apache's mod_rewrite

Debugging .htaccess is hell, and RewriteRules in particular if they are not working as expected. But fear not! RewriteLog will help you out. \
Add this to your vhost's configuration:

RewriteLog "/tmp/rewrite.log"
RewriteLogLevel 9

After that, restart your Apache httpd and tail the above logfile.

When you are done and all is well: remember to remove those entries again, or set the log level to 0, to switch off rewrite logging.

Force absolute URLs for parts of a view or controller

You know that you can force absolute URLs throughout a response. Now you want to modify URLs similarly, but only in parts of a view (or controller) logic. Here is how.


Note: this has only been tested on a Rails 2 application. It should work similarly for Rails 3.


Put this into your ApplicationController:

def rewrite_options(*args)
  options = super
  options.merge!(:only_path => false) if @with_full_urls
  options
end...

How to solve Selenium focus issues

Selenium cannot reliably control a browser when its window is not in focus, or when you accidentally interact with the browser frame. This will result in flickering tests, which are "randomly" red and green. In fact, this behavior is not random at all and completely depends on whether or not the browser window had focus at the time.

This card will give you a better understanding of Selenium focus issues, and what you can do to get your test suite stable again.

Preventing accidental interaction with the Selenium window
--------------------...

A jQuery plugin for producing bar charts from tables.

As the title says: this jQuery plugin creates bar charts from HTML tables. It comes in some different flavors.

Check the examples page: http://alphagov.github.com/magna-charta/.

CSS: Vertically center with display: table-cell

The classical scenario: There's a parent div element and you want to center some arbitrary child element vertically inside of it. Here's how you do it (also try this jsfiddle).

The children need to be block elements.

The HTML

<div class="parent">
  <div class="child"></div>
  <div class="child"></div>
  ...
</div>

The CSS

.parent {
  display: table-cell;
  vertical-align: middle;
  width: 500px;
  height: 300px;
}
      
.child {}

When .child elements are inline elements, add `display: bl...