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:
- Two concurrent requests try to create a user with the same name (and we want user names to be unique)
- The requests are accepted on the server by two worker processes who will now process them in parallel
- Both requests scan the
users
table and see that the name is available - 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.
- Open the site to test in the browser of your choice. Do not login yet.
- 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:
- Modern mobile devices have high-density displays where 1px in your CSS e.g. corresponds to 2.25, 4, ... physical pixels on the screen hardware.
- Difficult APIs
- Inconsistent APIs
- Screen orientation can change when the user rotates h...
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
- 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 @import
s 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 RewriteRule
s 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...