Inspecting the page content in a Cucumber session
When you need to see the content of a page (i.e. not all the HTML but the relevant text body)
- you can do
pp (html_content)- pp will format the html String human readable pretty printed
- where html_content can be replaced by one of the following commands:
Rails
body or response.body
Capybara:
page.driver.html.contentpage.body
Webrat:
Nokogiri::HTML(response.body).content
The returned strings can be cleaned up by calling .gsub(/^\s*$/, '').squeeze("\n") on them.\
Although this may be useful for d...
Check if a field or button is disabled with Cucumber
Using this step definition you can check if any form field (text field, checkbox, etc) or button is disabled:
Then the "Name" field should be disabled
And the "Save" button should be disabled
But the "Locked" field should not be disabled
Capybara
This step part of Spreewald.
Webrat
Then /^"([^\"]*)" should( not)? be disabled$/ do |label, negate|
attributes = field_labeled(label).element.attributes.keys
attributes.send(negate ? :should_not : :should...
Encode or decode HTML entities
Use the htmlentities gem.
Encoding works like this:
require 'htmlentities'
coder = HTMLEntities.new
string = "<élan>"
coder.encode(string) # => "<élan>"
coder.encode(string, :named) # => "<élan>"
coder.encode(string, :decimal) # => "<élan>"
coder.encode(string, :hexadecimal) # => "<élan>"
Decoding works like this:
require 'htmlentities'
coder = HTMLEntities.new
string = "élan"
cod...
Virtual attributes for array fields
When a has_many association basically serves to store a list of associated strings (tags, categories, ...), it can be convenient to represent this association as a string array in the containing model. Here is an example for this pattern from the acts-as-taggable-on gem:
post = Post.last
p post.tag_list # ['foo', 'bar', 'baz']
post.tag_list = ['bam']
p post.tag_list # ['bam']
This string array tag_list is magical in several ways:
- It is read from and written to a `has...
Virtual attributes for integer fields
Note that this card is very old. You might want to use ActiveType for your auto-coerced virtual attributes instead.
We sometimes give our models virtual attributes for values that don't need to be stored permanently.
When such a virtual attribute should contain integer values you might get unexpected behavior with forms, because every param is a string and you don't get the magic type casting that...
Manipulate an array attribute using multiple check boxes
E.g. when you're using a tagging gem, you have seen virtual attributes that get and set a string array:
post = Post.last
puts post.tag_list # ['foo', 'bar', 'baz']
post.tag_list = ['bam']
puts post.tag_list # ['bam']
If you would like to create a form displaying one check box per tag, you can do this:
- form_for @post do |form|
= form.check_box :tag_list, { :multiple => true }, 'foo', nil
= form.check_box :tag_list, { :multiple => true }, 'bar', nil
=...
Test that a select option is selected with Cucumber
This step tests whether a given select option comes preselected in the HTML. There is another step to test that an option is available at all.
Capybara
Then /^"([^"]*)" should be selected for "([^"]*)"(?: within "([^\"]*)")?$/ do |value, field, selector|
with_scope(selector) do
field_labeled(field).find(:xpath, ".//option[@selected = 'selected'][text() = '#{value}']").should be_present
end
end
Webrat
...
Useful collection of Sass mixins
This collection of Sass mixins enables cross-browser styling (including IE with CSS3PIE) with less lines of code.
This enables PIE for IE up to version 8 only (the first part is not possible in Haml, so use ERB):
<!--[if !IE]><!-->
<%= stylesheet_link_tag 'screen', :media => 'screen' %>
<!--<![endif]-->
<!--[if lte IE 8]>
<%= stylesheet_link_tag 'screen_with_pie', :media => 'screen' %>
<![endif]-->
These would be your two screen Sasses:
# screen_with_pie.sass
...
Problems with Rails 3 Remote Links and Forms Using jQuery .live() in IE
There is a problem with AJAX response handling for Rails 3 remote links and forms in Internet Explorer. This problem affects applications still using jQuery 1.4.2.
Aliases for routes
The following initializer provides an :alias => "my_route_name" option to restful routes in your route.rb. This simply makes the same route also available under a different ..._path / ..._url helpers.
For example,
map.resources :notes, :alias => :snippets
Gives you
notes_path, notes_url, new_note_path... #as always
snippets_path, snippets_url, new_snippet_path... #from the alias
Put this into an initializer:
Git: "Interactive reverts"
If you need to revert only parts of one or several commits the following workflow can help:
If you need to revert multiple changes, make a branch and squash it afterwards.
For every commit you need to revert, starting at the most recent, do:
git revert -n [COMMIT] #revert, but don't automatically commit
... #fix any conflicts
git reset #unstage all changes
git add -p #this will ask you for every change, whethe...
Generate a Unicode nonbreaking space in Ruby
Regular spaces and non-breaking spaces are hard to distinguish for a human.
Instead of using the HTML entity or code like " " # this is an nbsp, use a well-named helper method instead.
def nbsp
[160].pack('U*')
end
160 is the ASCII character code of a non-breaking space.
Rails 3 Remote Links and Forms: A Definitive Guide
Thanks to habits engrained by Rails 2’s link_to_remote and remote_form_for, we expect that Rails 3 would also handle the AJAX response for our remote links and forms. But it doesn’t; it leaves that for you.
Request a non-HTML format in controller specs
If a controller action responds to other formats than HTML (XML, PDF, Excel, JSON, ...), you can reach that code in a controller spec like this:
describe UsersController do
describe '#index' do
it 'should be able to send an excel file' do
# stubs and expectations go here
get :index, :format => 'xls'
end
end
end
Remember that both the :format parameter and the HTTP_ACCEPT header can m...
Get the current layout's name in a view or partial
This returns the name (including path) of your current layout:
response.layout
=> "layouts/admin" # inside views that are using the 'admin' layout
You most likely do not need the full path, so go ahead and do this:
File.basename(response.layout)
=> "admin"
Use form_for without the enclosing form tag
In rare cases you might need something like form_for (for using form builder methods on the resulting block element) but without the surrounding form. One such case would be updating some of a form's fields via XHR.
You can simply use Rails' fields_for to do things like this in your views (HAML here):
- fields_for @user do |form|
= form.label :email, 'E-Mail'
= form.text_field :email
You will only receive the form content you gave, no hidden inputs incl...
Generate a path or URL string from an array of route components
When using form_for you can give the form's target URL either as a string or an array:
form_for(admin_user_path(@user)) do ... end
# same as:
form_for([:admin, @user]) do ... end
Same for link_to:
link_to("Label", edit_admin_user_path(@user))
# same as
link_to("Label", [:edit, :admin, @user])
polymorphic_path and polymorphic_url
If you would like to generate a path or URL string from an array of route components just as form_for does, you can use polymorphic_path or polymorphic_url:
polymorphic...
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.
Pay attention to the order of your submit buttons
If you have several submit elements (inputs or buttons 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...
Places where cron jobs can hide
- In
/etc/crontab - In
/etc/cron.d/* - In
/etc/cron.hourly/* - In
/etc/cron.daily/* - In
/etc/cron.weekly/* - In
/etc/cron.monthly/* - In the personal crontab of any user. This is a magic file you can view with
crontab -land edit withcrontab -e. You'll need tosuto the respective user to view or edit her crontab.
Use Sass without Rails
You don't need a Rails application to use Sass. Even when you're working on a static site you can generate your CSS through Sass.
- Install Sass with
sudo gem install haml - Create a folder
sassin the folder, that stores your stylesheets, e.g.mkdir css/sass - In a separate terminal window, run
sass --watch css/sass:css. This will watch your sass files for changes and rewrite stylesheets as required.
This even works on Windows.
Note about your .gitignore
You might want to change our [typical .gitignor...
Define an array condition that selects on dynamic columns
For some reason you want to define a find condition in array form. And in that condition both column name and value are coming from user input and need to be sanitized.
Unfortunately this works in SQLite but does not in MySQL:
named_scope :filter, lambda { |attribute, value|
{ :conditions => [ 'articles.? = ?', attribute, value ] }
}
The solution is to use [sanitize_sql_array](http://apidock.com/rails/ActiveRecord/Base/sa...
Copying validation errors from one attribute to another
When using virtual attributes, the attached trait can be useful to automatically copy errors from one attribute to another.
Here is a typical use case where Paperclip creates a virtual attribute :attachment, but there are validations on both :attachment and :attachment_file_name. If the form has a file picker on :attachment, you would like to highlight it with errors from any attribute:
class Note < ActiveRecord::Base
has_attached_file :attachment
validates_attachment_presence :a...
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.
Variant: 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.
...