Sonntag, 30. August 2015

Render Rails layout partials!

In Ruby on Rails in general repetitions in views are eliminated by partials.
This works for most cases. Widgets or complex controls also often consist of an HTML skeleton that repeats itself. However, they also contain some content HTML that differs.
As an example, a modal dialog is used (people/_people.html.erb):

A modal dialog for other resources would look alike. They only would differ in the HTML within the modal body. The rest (header, footer, etc.) were just repetition. It therefore makes sense to extract the HTML skeleton into a partial.
The content can consist of any HTML. To pass it to the partial modal as a variable is not an option. But there is an elegant solution:
ActionView#render provides the option :layout. It is often used to render a page in a certain layout. But it also is intended to render a partial in a "Layout" (people/_people.html.erb):
<%= render layout: 'shared/modal' do %>
  <%= render @people %>
<% end %>
und das wiederverwendbare dialog widget (shared/_modal.html.erb):

The entire HTML skeleton was extracted into the partial. The content can be passed as a block and injected with yield to the right place.
Even more complex widgets can be shared with this approach.
For example, if the partial consumers require a more flexible set of buttons (besides the Cancel button), ActionView#content_for comes into play.
The extended partial shared/_modal.html.erb:

and the consumer template people/_people.html.erb:
<%= render layout: 'shared/modal' do %>
  <%= render @people %>
  <% content_for :buttons do %>
    <%= link_to 'print', people_path(format: :pdf) %>
  <% end %>
<% end %>
Further articles of interest:

Supported by Ruby 2.2.1, Ruby on Rails 4.2.1

Sonntag, 23. August 2015

Batch huge ActiveRecord collections!

To process large amounts of data may force the server to its knees. For example, a background job processing statistical data. The same can also apply to data migrations.
Much of the resources are consumed by ActiveRecord object instantiations. If there is no alternative to instantiate the ActiveRecord objects, Ruby on Rails provides the possibility of batch processing with ActiveRecord::Batches#find_in_batches.
Therefore, instead of:
Order.all.each(&:calculate_summer_sale!)
The example is trivial, but in the case of many orders, it is not predictable how much load will be on the production server. In fact the entire set of objects is loaded and held in the memory until the final pass is completed.
However, the risk can be restricted by batching:
Order.where(invoiced: false).find_in_batches(batch_size: 500) do |orders|
  orders.each(&:calculate_summer_sale!)
end
In the example, 500 orders are processed and loaded into memory per batch run.
The :batch_size is optional. The default value is 1000.
The orders collection is processed with each only. Then ActiveRecord::Batches#find_each is a more concise version (this time with a named scope):
Order.not_invoiced.find_each(batch_size: 500) do |order|
  order.calculate_summer_sale!
end
Both versions principle are similar. They divide the objects in batches based on the ID, which is why the query methods ActiveRecord::QueryMethods#order and ActiveRecord::QueryMethods#limit can not be used.
Another option is :start. It allows the batches to be split across multiple processes.
For example, the first 20 batches are processed from the first process (each with 1000):
Order.where(id: 1..20_000).find_each do |order|
  order.calculate_summer_sale!
end
and the remaining from the second process:
Order.find_each(start: 20_000).each do |order|
  order.calculate_summer_sale!
end
ActiveRecord::QueryMethods#select should be used cautiously. The example:
Order.select('total').find_each(batch_size: 500) do |order|
  order.calculate_summer_sale!
end
Smaller objects are instantiated and therefore it generates less burden. But only a batch of 500 objects actually is processed, since the batching is based on the primary key, which was not selected. At least the ID would have to be selected with:
Order.select('id, total').find_each(batch_size: 500) do |order|
  order.calculate_summer_sale!
end

Further articles of interest:

Supported by Ruby 2.2.1, Ruby on Rails 4.2.1

Sonntag, 16. August 2015

Dive into the Hash#default_proc!

Hash without Proc

A Ruby Hash can be initialized in several ways:
config = {}
config = Hash.new
In both cases the associative array returns nil, when accessed with a key which does not exist:
config[:production]
=> nil
The Hash was instantiated without a Proc:
config.default_proc
=> nil
If you want to execute a nested access, an exception is raised:
config = Hash.new
config[:production][:log] = 'log.txt'
NoMethodError: undefined method '[]=' for nil:NilClass
because Nil#[] is not defined.

Hash with Proc

A Hash also can be instantiated with a block:
config = Hash.new{ |hash, key| rand(1..10) }
The access to an unknown key will always return a value (random number between 1 and 10):
config[:production]
=> 4
config[:production]
=> 9
The reason is the Hash object got a default Proc during instantiation. If the accessing key is not included, the Proc is executed. In that example the Hash itself keeps being empty:
config
=> {}
Of course, the Proc also can do more meaningful stuff:
config = Hash.new{ |hash, key| hash[key] = Hash.new }
config[:production][:log] = 'log/production.log'
Although the key :production has never been initialized, no exception is thrown. The Hash was even extended as expected:
config
=> {:production=>{:log=>"log/production.log"}}
The Proc object can also be requested again:
config.default_proc
=> #
However, the Hash still can not be accessed infinitely deep:
config[:production][:log][:path] = 'log/production.log'
NoMethodError: undefined method '[]=' for nil:NilClass

Hash with Proc for infinite access

When a Hash has to provide infinite deep access without raising an exception, a default Proc has to be passed recursively by passing the default_proc to the accessed Hash value:
config = Hash.new do |hash, key| 
  hash[key] = Hash.new(&hash.default_proc)
end
The Hash owns a default Proc:
config.default_proc
=> #
If the accessing key is not available, no matter which depth, it will always create a new Hash object by default:
config[:production][:log][:path] = 'log/production.log'
config
=> {:production=>{:log=>{:path=>"log/production.log"}}}
A default Proc is also assignable after instantiating the Hash:
config = {}
config.default_proc = proc{ |hash, key| hash[key] = Hash.new(&hash.default_proc) }
config[:production][:log][:path] = 'log/production.log'
config
=> {:production=>{:log=>{:path=>"log/production.log"}}}
Not infinite depth, but very deep:
config[0][1][2][3][4][5][6][7][8][9]
=> {}

Further articles of interest:

Supported by Ruby 2.2.1

Sonntag, 9. August 2015

Set associations in FactoryGirl!

Fixtures are not suitable for testing. They are difficult to maintain and require explicit instantiation of test objects. This is particularly true for associations.
Instead, factories should be be used to generate test objects. The widespread gem Factory Girl lends itself to it. For example, the models/person_spec.rb:
require 'active_record_spec_helper'
require 'person.rb'
require 'address.rb

describe Person do
  subject { FactoryGirl.build :person }

  describe "validations" do
    FactoryGirl.create :address
    if { is_expected.to validate_presence_of(:address) }
  end
end
A person shall only be valid if it also has a valid address. The factories/address.rb:
FactoryGirl.define do
  factory :address do
    street 'Main street'
    number 1
    zip 12345
  end
end
The factories/person.rb:
FactoryGirl.define do
  factory :person do
    name 'Christian'
    surname 'Rolle'
    address_id 1
  end
end
The people factory has defined an address_id association by setting a plain ID. That is very fragile. Especially since a valid person is expected to own a valid address object.
The association could be mocked or the FactoryGirl association feature could be used for some reasons (factories/person.rb):
FactoryGirl.define do
  factory :person do
    name 'Christian'
    surname 'Rolle'
    association :address, strategy: :build
  end
end
The address association will not be actively saved. That saves touching the database in each test and therefore speed up the test tremendously (models/person_spec.rb):
require 'active_record_spec_helper'
require 'person.rb'
require 'address.rb

describe Person do
  subject { FactoryGirl.build :person }

  describe "validations" do
    if { is_expected.to validate_presence_of(:address) }
  end
end
In most tests the associations presence is sufficient. If indeed a stored association is required (eg named scopes), that explicit saving approach is way more expressive.
Further articles of interest:

Supported by Ruby 2.2.1, Ruby on Rails 4.2.1, RSpec 3.3.2 and FactoryGirl 4.5.0

Sonntag, 2. August 2015

Speed up ActiveRecord callback tests!

ActiveRecord model tests are often slow when they touch the database.
For example, the simple create callback test in the person_spec.rb:
require 'active_record_spec_helper'
require 'person.rb'

describe Person do
  subject { FactoryGirl.build :person }

  describe "#create" do
    it "should be active" do
      subject.active = nil
      subject.save
      expect(subject.active).to be_truthy
    end
  end
end
It is expected that any new person should be active after creation. The test ensures this.
However, it can be optimized. It is absolutely unimportant to the relevance of the tests that the record is actually stored after passing through the callbacks. The ActiveRecord has already been extensively proven its functionality in the Ruby on Rails test suite.
So there neither has to be opened a connection to the database, nor fired a SQL statement. Therefore, the person_spec.rb also can look like:
require 'active_record_spec_helper'
require 'person.rb'

describe Person do
  subject { FactoryGirl.build :person }

  describe "#create" do
    it "should be active" do
      subject.active = nil
      subject.run_callbacks :create
      expect(subject.active).to be_truthy
    end
  end
end
The test still ensures a new person to be active. And it consumes way less resources. ActiveSupport::Callbacks#run_callbacks calls the callbacks, but without final persistence. A comparison makes the performance difference obvious. With database:
ubuntu$ rspec spec/models/person_spec.rb

Finished in 0.12141 seconds (files took 2 seconds to load)
Without database:
ubuntu$ rspec spec/models/person_spec.rb

Finished in 0.04964 seconds (files took 2 seconds to load)
At first glance it does not look impressive.
But the same test without touching the database is more than twice as fast. The more more callback tests do exist in the project, the more impressive the numbers will be.
Further articles of interest:

Supported by Ruby 2.2.1, Ruby on Rails 4.2.1 and RSpec 3.3.2

Sonntag, 26. Juli 2015

Put your ActiveRecord tests on speed!

Suppose your ActiveRecord models already represent the single responsibility pattern. In other words, you've outsourced logic that is not necessarily in a model.
The models are indeed slimmed down, but testing it still takes a long time. Give them some speed.
For example, this simple person_spec.rb based on a standard spec_helper.rb:
require 'spec_helper'

describe Person do
  subject { FactoryGirl.build :person }

  describe "Validation" do
    it { is_expected.to validate_presence_of(:name) }
  end
end
lasts around half a minute.:
ruby$ time RSpec spec/models/person_spec.rb

real 0m32.271s
user 0m15.914s
sys 0m2.938s
and by far the most of the time is needed to start up the Rails application.
In comparison, a processing time for the same tests:
ruby$ time RSpec spec/models/person_spec.rb

real 0m2.977s
user 0m2.548s
sys 0m0.327s
is faster by a factor of about 10.
This can only be achieved if only the necessary modules are loaded by Ruby on Rails. The used spec/active_record_spec_helper.rb looks like:
require 'active_record'
require 'factory_girl'
require 'shoulda/matchers'

connection_info = YAML.load_file("config/database.yml")["test"]
ActiveRecord::Base.establish_connection(connection_info)
RSpec.configure do |config|
  config.around do |Example|
    ActiveRecord::Base.transaction do
      example.run
      raise ActiveRecord::Rollback
    end
  end
end
For the file person_spec.rb then only the requirements have to be changed:
require 'active_record_spec_helper'
require 'person'

describe person do
  subject { FactoryGirl.build :person }

  describe "Validation" do
    it { is_expected.to validate_presence_of(:name) }
  end
end
Each additionally required model must also be explicitly required, which is an advantage. This way the test clearly points out, that there are additional dependencies. They should be dissolved if possible.
Cheers to Corey Haines for promoting this topic.
Further articles of interest:

Supported by Ruby 2.2.1, Ruby on Rails 4.2.1 and RSpec 3.3.2

Sonntag, 31. Mai 2015

Clean up nested forms with form objects in Rails!

Nested forms consist of form fields representing at least 2 objects. For example one form with user and address attributes. In Ruby On Rails nested forms very often are built with ActiveRecord::NestedAttributes::ClassMethods#accepts_nested_attributes_for and ActionView::Helpers::FormHelper#fields_for. Meanwhile it is proven going that path is a bad idea for several reasons. I fiddles with awful request parameters, burdens the model with false responsibilities and is hard to test. But there is an alternative, which decreases complexity: form objects.
Whenever:
  1. Nested forms
  2. Virtual model attributes
  3. Multiple varying forms for one resource
are required, form objects have to be considered, because they:
  1. Extract responsibility from the model objects
  2. Decouple models from forms
  3. Simplify forms
  4. Flatten parameter hashes and therefore simplify parameter check
  5. Simplify form handling when there are multiple different forms attached to one resource
The more a form is getting complex the more an appropriate form object is the solution.
For example a user form with address data has to be saved at once. First the Address model (address.rb):
class Address < ActiveRecord::Base
  validates :street, :number, presence: true
end
Starting from the original model object user.rb:
class User < ActiveRecord::Base
  belongs_to :address
  validates :name, presence: true
  accepts_nested_attributes_for :address
end
a new form object class (user_address.rb) has to be created to achieve the goal:
class UserAddress
  include ActiveModel::Model
  validates :name, :street, :number, presence: true
  delegate :name, :save, to: :user
  delegate :street, :number, to: :address

  def attributes= new_attributes
    user.attributes = new_attributes.slice :name
    address.attributes = new_attributes.slice :street, :number
  end 

  def user
    @user ||= User.new
  end 

  def address
    @address ||= user.build_address
  end 
end
The UserAddress is a lightweight plain old Ruby object including the ActiveModel::Model, which just means including validation and conversion stuff. To marry User and Address there is a reader acessor for each object and also delegators to their required attribute acessor methods. At least there is an writing accessor for all attributes which just fills both objects.
At first sight the form object seems to cost more effort, than just using accepts_nested_attributes_for, but it offers more flexibility especially when the objects get more complex. Furthermore form logic baggage is extracted from the User model object, which is NOT responsible for it. And the good thing is, the controller and the view stuff is way cleaner through the form object.
The original working but awful nested form (users/_form.html.haml)
= form_for @user do |user_form|
  .text
    = user_form.label :name
    = user_form.text_field :name
  = user_form.fields_for :address do |address_fields|
    .text
      = address_fields.label :street
      = address_fields.text_field :street
    .text
      = address_fields.label :number
      = address_fields.text_field :number

  = user_form.submit 'Save'
could be way cleaner, if it looked like:
= form_for @user_address do |f| 
  .text
    = f.label :name
    = f.text_field :name
  .text
    = f.label :street
    = f.text_field :street
  .text
    = f.label :number
    = f.text_field :number

  = f.submit 'Save'
Please note the @user_address representing the form object and the straightforward form without any nesting.
Also compare the parameter hash from the nested:
"user" => { 
  "name" => "Chris", 
  "address_attributes" => { 
    "street" => "Main street", 
    "number" => "1" 
  } 
}
to the flattened:
"user_address" => { 
  "name" => "Chris", 
  "street" => "Main street", 
  "number" => "1" 
}
Finally even the original controller (controllers/users_controller.rb):
class UsersController < ApplicationController  
  def new 
    @user = User.new
    @user.build_address
  end 

  def create
    @user = User.new 
    @user.attributes = user_params
    @user.save
  end 
  private
  def user_params
    params.require(:user)
      .permit(:name, address_attributes: [:street, :number])
  end 
end
can be moved to the new resource (controllers/user_addresses_controller.rb):
class UserAddressesController < ApplicationController  
  def new 
    @user_address = UserAddress.new
  end 

  def create
    @user_address = UserAddress.new 
    @user_address.attributes = user_address_params
    @user_address.save
  end 
  private
  def user_address_params
    params.require(:user_address)
     .permit(:name, :street, :number)
  end 
end
having an easier parameter check.
Even that small example illustrates how nested forms can be simplified with lots of nice side effects.
Further articles of interest:

Supported by Ruby 2.2.1 and Ruby on Rails 4.2.1

Sonntag, 24. Mai 2015

Use SASS for CSS!

Ruby On Rails ships with SASS as CSS extension and there is a reason why.
It should be preferred over plain CSS because SASS:
  1. adds very useful features like variables and mixins
  2. allows nesting for reducing selector overhead and increasing readability by mapping the selectors depth
  3. adds properties like control directives and inheritance
  4. provides functions for colors, strings and lists
For example a pure CSS file people.css styles a toggle button and its look switching between the two states CSS based:
.icon:before{
  font-family: "Glyphicons Halflings";
}
.chevron-up:before{
  content: "\e113";
}
.chevron-down:before{
  content: "\e114";
}
#person input.toggle{
  display: none;
}
#person input.toggle:checked + .icon.chevron-down:before{
  content: "\e114";
}
styling the HTML snippet:
suffers from several point of views:
  1. even in that tiny CSS it repeats the DOM selector structure over and over (e.g. "#person input.toggle")
  2. a general style (e.g. content: "\e114";) has to be repeated if it has to be used in different contexts.
  3. styles belonging to the same selector structure are separated (e.g. "#person input.toggle" and "#person input.toggle:checked")
Nesting selectors and inheriting from previous defined classes solve the issues. The exactly same CSS can be generated by a SASS file people.css.scss like:
.icon:before{
  font-family: "Glyphicons Halflings";
}
.chevron-up:before{
  content: "\e113";
}
.chevron-down:before{
  content: "\e114";
}
#person{
  input.toggle{ display: none; }
  &:checked + .icon.chevron-up:before{
    @extend .chevron-down;
  }
}
The #person specific CSS was improved by nesting the selectors below #person and input.toggle. The @extend directive allows chevron-up icons to inherit their content from the more general chevron-down class.
Mixins also are nice. Whenever you want the output of the inherited style to change depending on how you call it, mixins are to be preferred over @extend. For example:
.width25{
  width: 25%;
}
.width50{
  width: 50%;
}
.width100{
  width: 100%;
}
#person .icon{
  display: block;
}
and the HTML:
cries for a inheritance in SASS:
@mixin .width($percent){
  width: $percent;
}
#person .icon{
  @include width(50%);
  display: block;
}
and in result even the HTML can be cleaned up by removing the nasty width class:
Variables not only help to assign parameters, they also help to dry out value repetition. For example:
.icon{
  background-color: #5CB85C;
  color: #A347A3;
}
.icon:first-child{
  background-color: #5CB85C;
  color: #A347A3;
}
which just styles the color and the background-color for icons, but inverting the colors for each first icon. The same with SASS:
$brand-primary: #5CB85C;
$brand-invert: invert($brand-primary);

.icon{
  background-color: $brand-primary;
  color: $brand-invert;
  &:first-child{
    background-color: $brand-invert;
    color: $brand-primary;
  }
}
using the variables $brand-primary and $brand-invert for defining the colors globally. Please note variables should be defined in a separate variables.css.scss
The inverted color code is calculated by the SASS function invert(), which ensures the invert color is always inverted.
SASS offers a lot more for many more use cases. Reading the well written SASS documentation helps to solve them.
Further articles of interest:

Supported by Ruby 2.1.1 and Ruby on Rails 4.1.8

Sonntag, 17. Mai 2015

Use HAML for Rails templates!

Ruby On Rails ships with ERB as templating system. It is simple and high generalized. Its flexibility is also its severest drawback.
A more suitable HTML templating system would:
  1. be tightly focused on generating HTML pages
  2. demand correct intendation
  3. reduce HTML tag verbosity and therefore increase readability
HAML is such a templating system and very common in the Ruby framework world.
It is easy to integrate by adding:
gem 'haml'
to the Gemfile.
A simple user.html.erb file:
<h1>Welcome <%= @user.name %></h1>
<div id="friends">
  <% @user.friends.each do |friend| %>
    <div id="<%= dom_id friend %>" class="friend">
      <%= friend.name %>
    </div>
  <% end %>
</div>
can refactored by creating the user.html.haml containing:
%h1= @user.name
#friends
  - @user.friends.each do |friend|
    .friend{ id: dom_id(friend) }= friend.name
The result is way shorter. HAML is well documented.
Please note that HAML forces you to take care of correct indentation. Otherwise it might crash with errors like:
Inconsistent indentation: 6 spaces used for indentation, 
but the rest of the document was indented using 4 spaces.
when there is a indent missing.
Or a little less intuitive:
SyntaxError - syntax error, unexpected keyword_ensure, 
expecting keyword_end
when indenting a Ruby block (like an interator) was incorrect.
Or even harder to get is unintentional DOM structure by wrong indentation.
Anyway HAML forces to indent correctly because whitespaces matter. And that is a benefit, because it helps to write cleaner HTML.
Further articles of interest:

Supported by Ruby 2.1.1 and Ruby on Rails 4.1.8

Sonntag, 3. Mai 2015

Specify Ruby method consumer fallbacks!

A public API is not always as simple as getting or setting a value. Especially when it comes to different expectations on unexpected behaviour. Should an exception be raised, or should it be handled. Best bet is to let the API consumer decide.
The Hash#fetch is such a Ruby example:
 %w(Ruby Java).fetch(0)
=> "Ruby"
and it raises the KeyError exception, when something went unexpected:
 %w(Ruby Java).fetch(2)
=> IndexError: index 2 outside of array bounds: -2...2
but the API provides a user friendly way to deal with unexpected behaviour. It just delegates the decision to the consumer. There are 3 options. First one is capturing the exception like:
begin
  %w(Ruby Java).fetch(2)
rescue IndexError
  puts "Python is missing."
end
or a more convenient way:
%w(Ruby Java).fetch(2, "Add a language.")
by simply assigning the fallback value as the second parameter. The third way to deal with the unexpected behaviour is passing a block:
%w(Ruby Java).fetch(2) { |index| 
  "Add a language at position #{index}." 
}
That consumer friendly approach not only applies to Hash#fetch but also to Hash#delete and many others. And it should also be adopted to the own API if required.
For example:
class Person
  def from_csv file
    File.open file
  end
end
should be refactored to:
class Person
  def from_csv file, &fallback
    File.open file
    rescue Errno::ENOENT => error
    if block_given?
      yield(error, self)
    else
      raise
    end
    self
  end
end
Now it is up to the consumer how to deal with the exceptional behaviour:
Person.new.from_csv('person_1.csv')
=> Errno::ENOENT: No such file or directory @ rb_sysopen - person_1.csv

Person.new.from_csv('person_1.csv') { |e| 
  raise IOError.new e.message 
}
=> IOError: No such file or directory @ rb_sysopen - person_1.csv

person = Person.new.from_csv('person_1.csv') { |e, person| 
  person.name = 'unknown' 
}
=> #<Person:0x00000005303f90 @name="unknown">
but the method itself can be refactored even a little more to:
class Person
  def from_csv file, &fallback
    fallback ||= ->(error) { raise }
    File.open file
    rescue Errno::ENOENT => error
    fallback.call(error)
    self
  end
end
It works the same but removes the awful if/else condition by setting up a default lambda.
Further articles of interest:

Supported by Ruby 2.1.1

Sonntag, 26. April 2015

Compare Ruby objects with Threequals!

Apart from simple comparision with == or eql? there is a another one: Object#=== aka Threequal.
Its intention is to provide "Case Equality". The Documention furthermore states:

For class Object, effectively the same as calling #==, but typically overridden by descendants to provide meaningful semantics in case statements.

It is meant to to be overwritten!
In some classes it is already achieved. For example Range#===:
(1..5) === 3
=> true
So there is a comparision going on between two kind of objects, a Range and a Fixnum. Briefly the Threequal "operator" technically is nothing more than a method expecting a parameter, similar to == or +.
But this one is special. The Threequal also is called when a case statement tries to compare. The Range class once again:
case 24
when 0..18
  'Underweight'
when 18..25
  'Normal weight'
else
  'Adiposity (overweight)'
end
=> 'Normal weight'
...Phew.
Please note, the Threequal has to be overwritten in the when-branches-object class, not in the one the case statement tries to compare.
So whenever semantic comparision is required overwriting Object#=== totally makes sense. Semantic comparision is emphasized. A Ruby On Rails example:
But setting up the models first:
rails g model Category name:string
rails g model Language name:string category_id:integer
class Category  < ActiveRecord::Base
  def self.[] name
    where(name: name).first
  end
 
  def === language
    language.category == self
  end
end

class Language < ActiveRecord::Base
  belongs_to :category
end
A language can belong to a category. The catogory Threequal method compares the assigned language category with itself. The class method Category#[] finds the corresponding object.
Creating a dynamic language:
ruby = Language.create name: 'Ruby', 
  category: Category.dynamic
and comparing it somewhere else:
case ruby
  when Category[:dynamic] then 'Awesome!'
  when Category[:static] then 'Huh.'
  else 'Anyway.'
end
=> "Awesome!"
returns the right answer.

Supported by Ruby 2.2.1 and Ruby on Rails 4.2.0

Sonntag, 19. April 2015

Follow the Ruby styleguide entirely! pt. 2

Programming styleguides are less a matter of taste. They are way more a matter of optimizing code readability. And following styleguides reveals own perception that others will read the code.
Code is communication. So programming styleguides are important!

1. Ternary Operator

Favor the ternary operator(?:) over if/then/else/end constructs for one liners. It is more common and obviously more concise.
# bad
result = if language.dynamic? then 'Awesome!' else 'Huh.' end

# good
result = language.dynamic? ? 'Awesome!' : 'Huh.'

2. Preprocess variables

Use &&= to preprocess variables that may or may not exist. Using &&= will change the value only if it exists, removing the need to check its existence with if.
# bad
if name
  name = name.downcase
end

# bad (even worse)
name = name ? name.downcase : nil

# ok
name = name.downcase if name

# good
name = name && name.downcase

# better
name &&= name.downcase

3. Indent case whens

Indent when as deep as case. It is the style established in the "Programming Ruby" (aka the Pickaxe book).
# bad
case language
  when 'Ruby'
    puts 'Awesome!'
  when 'Java'
    puts 'Huh.'
  else
    puts 'Let me see.'
end

# good
case language
when 'Ruby'
  puts 'Awesome!'
when 'Java'
  puts 'Huh.'
else
  puts 'Let me see.'
end

4. Constant references

Use :: only to reference constants (this includes classes and modules) and constructors (like Array() or Nokogiri::HTML()). Do not use :: for regular method invocation.
# bad
ActiveRecord::Base::reflections
Hash::new::keys

# good
ActiveRecord::Base.reflections
Hash.new.keys
ActiveRecord::Reflection::AssociationReflection::VALID_AUTOMATIC_INVERSE_MACROS
Nokogiri::HTML()

5. Procs

Prefer proc over Proc.new.
# bad
Proc.new { |n| puts n }

# good
proc { |n| puts n }

6. Array check

Use [*var] or Array() instead of explicit Array check, when dealing with a variable you want to treat as an Array, but you are not certain it is an array. [link]
# bad
paths = [paths] unless paths.is_a? Array
paths.each { |path| do_something(path) }

# good
[*paths].each { |path| do_something(path) }

# good (and a bit more readable)
Array(paths).each { |path| do_something(path) }

7. Parameter whitespaces

Use spaces around the = operator when assigning default values to method parameters: [link]
# bad
def do_something(arg1=:default, arg2=nil, arg3=[])
  # do something...
end

# good
def do_something(arg1 = :default, arg2 = nil, arg3 = [])
  # do something...
end
While several Ruby books suggest the first style, the second is much more prominent in practice (and arguably a bit more readable).

8. Multi line method chaning

Adopt a consistent multi-line method chaining style. Use trailing chaining.
When continuing a chained method invocation on another line, include the . on the first line to indicate that the expression continues:
# bad - need to read ahead to the second line to know that 
# the chain continues
one.two.three
  .four

# good - it's immediately clear that the expression continues 
# beyond the first line
one.two.three.
  four

9. Multi line Array literals

Align the elements of array literals spanning multiple lines.
# bad - single indent
languages = ['Ruby', 'Python', 'Java', 'C#', 'Scala',
  'CSS3', 'HTML5', 'XML', 'Javascript']

# good
languages = [
  'Ruby', 'Java', 'C#', 'Scala',
  'CSS3', 'HTML5', 'XML', 'Javascript'
]

# good
languages = 
  ['Ruby', 'Python', 'Java', 'C#', 'Scala',
   'CSS3', 'HTML5', 'XML', 'Javascript']

10. Use && and ||

The and and or keywords are banned. It is just not worth it. Always use && and || instead.
# bad
# boolean expression
if language.dynamic? and language.awesome?
  puts "It must be Ruby"
end

# control flow
language.dynamic? or language.awesome?

# good
# boolean expression
if language.dynamic? && language.awesome?
  puts "It must be Ruby"
end

# control flow
language.dynamic? || language.awesome?

Further articles of interest:

Supported by Ruby 2.2.1 and Ruby on Rails 4.2.0

Sonntag, 12. April 2015

Follow the Ruby styleguide! pt. 1

It is important to follow the Ruby styleguide. Some styles are controversial, but the most really make sense. Following them makes coding Ruby in a team a lot easier.

1. Indentation

Use two spaces per indentation level (aka soft tabs). No hard tabs:
# bad - four spaces
def some_method
    do_something
end

# good
def some_method
  do_something
end
it is one line in the VIM configuration file .vimrc:
set shiftwidth=2
and you are done.

2. Spaces

Use spaces around operators, after commas, colons and semicolons, around { and before }. Whitespace might be (mostly) irrelevant to the Ruby interpreter, but its proper use is the key to writing easily readable code:
# bad - missing whitespaces
sum=1+2
hash = {one:1,two:2,three:3}
a,b = 1,2
[1,2,3].each {|number| puts number}
class FooError<StandardError;end

# good
sum = 1 + 2
hash = { one: 1, two: 2, three: 3 }
a, b = 1, 2
[1, 2, 3].each { |e| puts e }
class FooError < StandardError; end
There are some exceptions:
# the exponent operator:
result = 2 ** 2 # instead of 2**2

# embedded expressions:
"string#{expr}" # instead of "string#{ expr }"

# array brackets:
[1, 2, 3] # instead of [ 1, 2, 3 ]

# method call:
do_something(:special) # instead of do_something( :special )

# negation:
!number? # instead of ! number?

# ranges:
1..5 # instead of 1 .. 5

3. Limited line length

Limit lines to 80 characters.

4. Parameter alignment

Align the parameters of a method call if they span more than one line. When aligning parameters is not appropriate due to line-length constraints, single indent for the lines after the first is also acceptable:
# starting point (line is too long)
def send_mail(source)
  Mailer.deliver(to: 'bob@example.com', from: 'us@example.com', subject: 'Important message', body: source.text)
end

# bad (double indent)
def send_mail(source)
  Mailer.deliver(
      to: 'bob@example.com',
      from: 'us@example.com',
      subject: 'Important message',
      body: source.text)
end

# good (normal indent)
def send_mail(source)
  Mailer.deliver(
    to: 'bob@example.com',
    from: 'us@example.com',
    subject: 'Important message',
    body: source.text
  )
end

5. Large numeric literals

Add underscores to large numeric literals to improve their readability:
# bad - how many 0s are there?
num = 1000000

# good - much easier to parse for the human brain
num = 1_000_000

6. Method arguments definition

Use def with parentheses when there are arguments. Omit the parentheses when the method doesn't accept any arguments:
# bad
def do_somthing()
 # do something
end

# good
def do_somthing
 # do something
end

# bad
def do_somthing_with_arguments arg1, arg2
 # do something
end

# good
def do_somthing_with_arguments(arg1, arg2)
 # do something
end

7. Expression result

Leverage the fact that if and case are expressions which return a result:
# bad
if condition
  result = x
else
  result = y
end

# good
result =
  if condition
    x
  else
    y
  end

8. Assignment operators

Use shorthand self assignment operators whenever applicable
# bad
x = x + y
x = x**y
x = x / y
x = x && y

# good
x += y
x **= y
x /= y
x &&= y

9. Variable initialization

Use ||= to initialize variables only if they are not already initialized:
# bad
language = language ? language : 'Ruby'
language = 'Ruby' unless language

# good - set language to Ruby, only if it's nil or false
language ||= 'Ruby'
But beware using ||= for initializing boolean variables. Consider what would happen if the current value happened to be false. Take a look:
# bad - would set enabled to true even if it was false
enabled ||= true

# good
enabled = true if enabled.nil?

10. Hashes

Use the Ruby 1.9 hash literal syntax when your hash keys are symbols:
# bad
hash = { :one => 1, :two => 2, :three => 3 }

# good
hash = { one: 1, two: 2, three: 3 }

Further articles of interest:

Supported by Ruby 2.1.1

Sonntag, 5. April 2015

Find the Rails easter egg!

Great software comes with an easter egg.
Beginning with the mozilla firefox, typing about:robots:
about:robots
into the address bar sends warm greetings.
The bash people on the other hand like to moo their cows around:
apt-get moo
and way more fun:
cowsay -p -f head-in Aaargh
The greatest editor (VIM) on earth helps to find the meaning of life by typing:
:help 42
Google is well known for easter eggs like their Google search (try to search anything).
Google Streetview also hides funny easter eggs. For example in the boondocks of the southpole you can see some nice pingings. And pingings are awesome.
But what about Ruby on Rails? It is great for sure, but where is their easter egg?
You can find it by typing:
(1..43).to_a.forty_two
into the rails console.
It is in Array and also in ActiveRecord::FinderMethods

Supported by Ruby 2.1.1 and Ruby on Rails 4.1.8

Sonntag, 29. März 2015

Create concise Ruby methods!

In the available Ruby method name space there are also method names, which are known from collection classes like Array or Hash. Since they are quite common it is easy to understand the intention of such methods, especially when used in a similar context.
For example a Person class dealing with a bunch of forenames:
class BankAccount
  attr_accessor :attributes
  def initialize attributes={}
    @attributes = attributes.assert_valid_keys :name, :amount
  end

  def add_money money
    @attributes[:amount] += money
  end

  def attribute attribute_name
    @attributes[attribute_name]
  end

  def attribute= attribute_name, value
    @attributes[attribute_name] = value
  end
end
and:
bank_account = BankAccount.new name: 'John', amount: 1000
bank_account.add_money 200
bank_account.attribute :amount
=> 1200
bank_account.attribute :amount, 2000
bank_account.attribute :amount
=> 2000
can be refactored to:
class BankAccount
  attr_accessor :attributes
  def initialize attributes={}
    @attributes = attributes.assert_valid_keys :name, :amount
  end

  def << money
    @attributes[:amount] += money
  end

  def [] attribute_name
    @attributes[attribute_name]
  end

  def []= attribute_name, value
    @attributes[attribute_name] = value
  end
end
Sending the messages is not only less typing but more important it is way more clear what happens:
bank_account = BankAccount.new name: 'John', amount: 1000
bank_account << 200
bank_account[:amount]
=> 1200
bank_account[:amount] = 2000
bank_account[:amount]
=> 2000

Supported by Ruby 2.1.1 and Ruby on Rails 4.1.8

Sonntag, 22. März 2015

Mark dangerous Ruby methods!

Methods that perform a permanent change to the object itself are potentially dangerous. That is why those methods should be marked with an exclamation mark at the end.
For example:
class BankAccount
  attr_accessor :amount
  def initialize amount
    @amount = amount
  end

  def withdraw_money amount
    @amount -= amount
  end
end
should be refactored to:
class BankAccount
  attr_accessor :amount
  def initialize amount
    @amount = amount
  end

  def withdraw_money! amount
    @amount -= amount
  end
end
and using it makes definitely clear, that the money is withdrawn permanently:
bank_account = BankAccount.new 1000
bank_account.withdraw_money! 200
=> 800
person.amount
=> 800

Supported by Ruby 2.1.1

Sonntag, 15. März 2015

Mark boolean methods in Ruby!

Some methods are special. They return a boolean value. Ruby has a convention for them: a question mark at the end.
The code:
class Person
  attr_accessor :age
  def intialize attributes={}
    @age = attributes[:age]
  end

  def is_adult
    @age > 18
  end
end
person = Person.new age: 20
person.is_adult
=> true
What does it express? Does it mean "The person is an adult" or does it ask "Is the person an adult"?
To make things clear the Ruby way is putting a question mark at the methods end:
class Person
  attr_accessor :age
  def intialize attributes={}
    @age = attributes[:age]
  end

  def adult?
    @age > 18
  end
end
person = Person.new age: 20
person.adult?
=> true
Using a question mark for boolean methods leaves no question.

Supported by Ruby 2.1.1

Sonntag, 8. März 2015

Avoid get or set prefixes in Ruby method names!

Getter and setter methods marked with get or set as prefix are from Java land, because it is an inflexible language.
Ruby is flexible and therefore provides a more concise way. A Javaish looking:
class Person
  def get_age
    @age
  end

  def set_age age
    @age = age
  end
end
should be refactored to:
class Person
  def age
    @age
  end

  def age= age
    @age = age
  end
end
Apart from using attr_accessor in those simple cases, it allows to send a more meaningful message:
person = Person.new
person.age = 30
person.age

Supported by Ruby 2.1.1

Sonntag, 1. März 2015

Prevent negations in Ruby!

Programming is about the communication between human being and the machine. So it is all about readable codes. That said, there are still some basic coding techniques widely used, which are less readable. Negation is one of them.
For example, it is common in Ruby to:
![1, 2, 3].empty?
=> true
in comparison to:
[1, 2, 3].any?
=> true
Asking for values is more straight forward than asking for not being empty. It removes the baggage of negation. Another example:
!"Ruby".blank?
=> true
can be refactored to:
"Ruby".present?
=> true
Object#present? is a monkey patch in Ruby on Rails, which is exactly the negation Object#blank? behind the scenes. But it is way more intentional.
Furthermore never do something like:
!11.even?
=> true
but instead:
11.odd?
=> true
The last negation example is not that awkward apparently:
puts "Non zero" unless 1.zero?
=> "Non zero"
but also can be refactored to the more optimistic:
puts "Non zero" if 1.nonzero?
=> "Non zero"
Please note that the Numeric#nonzero? returns self if the number is not zero (which is truish), nil (equated with false) otherwise.
Preventing negations is also about the own API. Hiding negations behind the API is absolutely reasonable.
Stay positive!
Further articles of interest:

Supported by Ruby 2.1.1 and Ruby on Rails 4.1.8

Sonntag, 15. Februar 2015

Store documents in MongoDB!

MongoDB has become the synonym for NoSQL databases. It is like the shiny new toy every kid wants to play around with. And that is why it also has become a synonym for abused technology unfortunately.
But MongoDB has not to be blamed for being abused and as long as MongoDB is used in cases for which it is meant to be used, everything is fine. Appropriate use cases are real documents. So whenever the requirement is:
  1. inconsistent data (storing the data as it was at that time, like documenting in its traditional meaning)
  2. ACID transaction for a single document
  3. very flexible object structure, which has to be changeable during runtime
The MongoDB installation on a Linux system is charming easy.
There are several gems for using MongoDB in a Ruby On Rails application under the hood. Mongoid is one of the recommended.
After adding it in the Gemfile:
gem 'mongoid'
a simple BirthCertificate model would look like:
class BirthCertificate
  include Mongoid::Document
  field :name
  field :date_of_birth, type: Date
end
Please note the model was not inherited from ActiveRecord::Base, but includes the Mongoid::Document, which makes it transact with MongoDB under the hood. Furthermore 2 fields were configured; name with the default String type and date_of_birth with Date type. Creating a new birth certificate in the Rails console:
BirthCertificate.create name: 'Robert Redford', 
  date_of_birth: Date.new(1936, 8, 18)
MongoDB also has a console for accessing the database (20150215_development). Starting it from bash:
mongo 20150215_development
and asking it for the created record (Attention, it is NoSQL!):
db.birth_certificates.find()
{
  "_id" : ObjectId("55281a5c616e740db0010000"), 
  "name" : "Robert Redford", 
  "date_of_birth" : ISODate("1936-08-18T00:00:00Z") 
}
If a further attribute had to be added, the class could be enhanced like:
class BirthCertificate
  include Mongoid::Document
  field :name
  field :date_of_birth, type: Date
  field :name_of_father
end
The new field name_of_father was introduced later for some reasons and creating a new birth certificate:
BirthCertificate.create name: 'Jennifer Shrader Lawrence', 
  date_of_birth: Date.new(1990, 8, 15), 
  name_of_father: 'Gary Lawrence'
Listing in MongoDB console again:
db.birth_certificates.find()
{ 
  "_id" : ObjectId("55281a5c616e740db0010000"), 
  "name" : "Robert Redford", 
  "date_of_birth" : ISODate("1936-08-18T00:00:00Z")
}
{
  "_id" : ObjectId("55281c4b616e740db0030000"), 
  "name" : "Jennifer Shrader Lawrence", 
  "date_of_birth" : ISODate("1990-08-15T00:00:00Z"), 
  "name_of_father" : "Gary Lawrence" 
}
makes the difference obvious. The older record has no name_of_father, which is important, because the old record should not be modified in any way. It is a document, which has to remain the same despite any structural evolution.
By the way, database migrations are lapsed for mongoid models.
There is way more to say about MongoDB and its features like aggregation and enterprise requirements like replication and sharding.
The flexibility is inviting, but please keep in mind, using MongoDB only makes sense, if inconistent data is wanted - the characteristic of real documents.

Supported by Ruby 2.2.1, Ruby on Rails 4.1.0 and MongoDB 3.0.2

Sonntag, 8. Februar 2015

Go with the Strategy pattern in Ruby!

Solving varying algorithms with the Template Method pattern is reasonable as long as inheritance is reasonable. Since inheritance also comes with some drawbacks, it should be avoided if possible. Especially when it comes to decoupling classes: prefer delegation.
The Strategy pattern also solves varying algorithms but takes advantage of delegation.
In a nutshell, the varying algorithms are extracted into several classes, which define the so called Strategy objects. Each object has the same named API message receiver, but follows a different strategy how to achieve its goal. Apart from the Strategy objects, there is the particular Context object. It is the context in which the strategy works.
The example Context class:
class Person
  attr_reader :id, :resource_name
  attr_accessor :strategy

  def initialize strategy
    @id = 1 
    @resource_name = 'people'
    @strategy = strategy
  end 

  def request
    strategy.query self
  end 
end
is characterized by some (hard coded for example reasons) values: @id and @resource_name. Furthermore the Person class is a proxy and its objects are persisted somewhere else. They can be requested via different kind of webservices, the different strategies. Adding 2 types of webservices as strategies:
require 'uri'
require 'net/http'
class WebserviceRequest
  attr_reader :domain

  def initialize domain
    uri = URI.parse domain
    @http = Net::HTTP.new uri.host, uri.port
    @http.use_ssl = false
  end 

  def query context
    raise "#{self.class}#query not yet implemented."
  end 
end

class SoapRequest < WebserviceRequest
  def query context
    @http.post "/#{context.resource_name}", 
      soap_body(context) { |c|
          "<m:GetPerson>
            <m:Id>#{c.id}</m:Id>
          </m:GetPerson>"
      }, { 'Host' => @http.address, 'Content-Type' => 'text/xml' }
  end 
private
  def soap_body context, &block
    "<?xml version='1.0'?>
      <soap:Envelope xmlns:soap='http://www.w3.org/2001/12/soap-envelope' soap:encodingStyle='http://www.w3.org/2001/12/soap-encoding'>
        <soap:Body xmlns:m='http://#{@http.address}/#{context.resource_name}'>
          #{yield(context)}
        </soap:Body>
      </soap:Envelope>"
  end
end

class RestRequest < WebserviceRequest
  def query context
    @http.get "/#{context.resource_name}/#{context.id}"
  end
end
There is a SOAP (ugh!) and a REST strategy. Both expect a domain address to be requested:
Person.new(RestRequest.new 'http://localhost').request
=> #<Net::HTTPOK 200 OK readbody=true>
Person.new(SoapRequest.new 'http://localhost').request
=> #<Net::HTTPNotFound 404 Not Found readbody=true>
Both requests send a HTTP request to localhost on port 80 with some parameters. Apparently the SOAP query was not the right strategy in the Person context.
But the pattern is obvious: the person Context object has a Strategy object and sends the query message to it with itself as the parameter. The method itself is the implementation detail, the varying part.
Strategies can be added as many as required. For example a Strategy to query a database:
class SqlRequest
  attr_reader :connection

  def initialize connection
    @connection = connection
  end
  
  def query context
    @connection.execute "SELECT * FROM #{context.resource_name} WHERE ID = #{context.id};"
  end
end
and
Person.new(SqlRequest.new database_connection).request
=> SELECT * FROM people WHERE ID = 1;
The advantage is the complete class decoupling. It only relies on duck typing. Any class can be a Strategy as long as it has the right interface.
Further articles of interest:

Supported by Ruby 2.1.1

Sonntag, 1. Februar 2015

Template method in Ruby!

Sharing business logic by inheritance is a common pattern in object oriented programming. But sometimes the piece of logic has very little variances, like:
class Bike
  def start
    "Check 2 tyres. Bike is started!"
  end
end

class Car
  def start
    "Check 4 tyres. Start gasoline engine. Car is started!"
  end
end
and:
Bike.new.start
=> "Check 2 tyres. Bike is started!"
Car.new.start
=> "Check 4 tyres. Start gasoline engine. Car is started!"
Quite static. Both classes seem to have something in common (they can be started and have a number of tyres to be checked before). But at the same point, they are specialized by the number of tyres and in having an engine to be started or none.
The template method pattern is a reasonable option to deal with such small variances. It is one of those patterns defined by the Gang of Four and fairly simple to implement.
The pattern is based on inheritance for the similarities (the template method), whereas the variances are separated by extracting them into appropriate methods, so called hook methods. The template method drives the bit that needs to vary, but it does so by making calls to abstract methods, which are then supplied by the concrete subclasses.
The template pattern is absolutely reasonable, when:
  1. inheritance is reasonable
  2. the logic equality is way more distinct than its variance
The example in a templated manner:
class Vehicle
  def start
    todos = ["Check #{tyres} tyres."]
    todos << "Start #{fuel} engine." if fuel
    todos << "#{self.class} is started!"
    todos.join(' ')
  end
private
  def tyres
    raise 'Called abstract method: tyres'
  end

  def fuel
    raise 'Called abstract method: fuel'
  end
end

class Car < Vehicle
private
  def tyres
    4
  end

  def fuel
    gasoline
  end
end

class Bike < Vehicle
private
  def tyres
    2
  end

  def fuel
    nil
  end
end
Since Ruby does not supply abstract methods, defining exception methods in the base class is common practice in Ruby world.
Even though the generalized start method (template method) now looks more complex, it dries out the repeated similarities and is way more flexible for further subclasses.
Please note the template method pattern only makes sense, when the algorithms are way more alike than different.
Even the refactored result can be improved. Abstract methods are the more static typed language way. It makes more sense for the base class Vehicle to simply supply a default implementation of these methods for the convenience of its subclasses:
class Vehicle
  def start
    todos = ["#{self.class} is started!"]
    todos.unshift "Start #{fuel} engine." if fuel
    todos.unshift "Check #{tyres} tyres." unless tyres.to_i.zero?
    todos.join(' ')
  end
private
  attr_reader :fuel, :tyres
end

class Car < Vehicle
private
  def tyres
    4
  end

  def fuel
    gasoline
  end
end

class Bike < Vehicle
  def tyres
    2
  end
end
and:
Bike.new.start
=> "Check 2 tyres. Bike is started!"
Car.new.start
=> "Check 4 tyres. Start gasoline engine. Car is started!"
Creating a new subclass can take advantage of the existing method structure required by the base class:
class Rocket < Vehicle
private
  def fuel
    "oxydizer"
  end
end
It works like a charm:
Rocket.new.start
=> "Start oxydizer engine. Rocket is started!"
Further articles of interest:

Supported by Ruby 2.1.1

Sonntag, 25. Januar 2015

Bitmask the boolean attributes!

Some database tables suffer from excessive boolean attributes. Especially when most are likely to be NULL.
Merging the boolean attributes into one single bitmasked integer attribute is a solution. Then the integer value represents multiple flags (booleans) bitwise. Metaphorical spoken: several boolean attributes are stacked into the value of one integer attribute
The advantages for bitmasking boolean attributes are:
  1. much lower attribute baggage: 1 integer (usually 4 bytes) can take up to 32 boolean attributes
  2. flexible database structure (a new boolean attribute does not require a database migration)
  3. readable semantic values (the values are meaningful compared to the boolean true/ false)
  4. dynamic access to the bitmask values, which feels more Rubyish
Although there are various pros, the downsides also have to be considered. Bitmasking definitely does not fit for every use case, like most patterns. Abusing it introduces more pain than relief, because it also:
  1. reduces readability in the database layer (the stacked integer value is hiding the meaningful attribute names)
  2. introduces a (very small) Ruby layer for processing the stacked values (back and forth)
  3. means to work around attribute representations, which rely on the database data type (like simple_form gem)
The gem bitmask_attribute lightens the workload for dealing with the bitmasking logic. It provides a nice API to deal with. So instead of a migration with only a few boolean attributes:
create_table :people do |t| 
  t.string :name
  t.boolean :product_owner, null: false, default: false
  t.boolean :developer, null: false, default: false
  t.boolean :scrum_master, null: false, default: false
  t.boolean :sales, null: false, default: false
end 
the same model can be refactored to:
create_table :people do |t| 
  t.string :name
  t.integer :roles
end 
The appropriate model:
class Person < ActiveRecord::Base
  bitmask :roles, 
    as: [:scrum_master, :product_owner, :developer, :sales]
end
and by now the bitmask can be used:
Person.values_for_roles
=> [:scrum_master, :product_owner, :developer, :sales]
person = Person.create name: 'Bob', 
  roles: [:scrum_master, :developer]
person.roles
=> [:scrum_master, :developer]
person.roles << :sales
person.roles
=> [:scrum_master, :developer, :sales]
person.roles? :developer
=> true
If the bitmask has to be represented by check boxes in the Ruby on Rails view:
<% Person.values_for_roles.each do |role| %>
  <%= check_box_tag 'person[roles][]', role, 
        @person.roles.include?(role), id: role %>
  <%= label_tag role, role.to_s.humanize %>
<% end %>
generates the HTML:








Using bitmask_attribute requires to think about the pros and cons in the forefront, because migrating the production data back to boolean attributes is awkward. Furthermore, when it comes to boolean attributes representing several states (especially when the combination of boolean attributes respresent those states), a state machine should be considered.
Further articles of interest:

Supported by Ruby 2.1.1 and Ruby on Rails 3.2.19

Sonntag, 18. Januar 2015

Filter the named parameters!

Named parameters are great for reducing complexity of method parameters in Ruby. Filtering the named parameters for relevance, by limiting the keys to the expected few, makes sense in some cases. Especially, if logic is bound to the API keywords.
An example Team class API could be:
class Team
  def initialize name, roles={}
    @name = name
    @roles = roles
  end

  def roles
    @roles.keys
  end
end
Team.new('Scrum', product_owner: 'Alice', 
  scrum_master: 'Bob').roles
=> [:product_owner, :scrum_master]
looks plausible.
But:
Team.new('Scrum', product_owner: 'Alice', 
  sales: 'Sarah').roles
=> [:product_owner, :sales]
is definitely not a Scrum team.
Every time the API expects certain named parameters, those have to be filtered, like:
class Team
  def initialize name, roles={}
    @name = name
    @roles = [:product_owner, :scrum_master, :developer].
      each_with_object(Hash.new) { |role, hash| 
        hash[role] = roles[role] if roles.has_key?(role) 
      }
  end

  def roles
    @roles.keys
  end
end
Team.new('Scrum', product_owner: 'Alice', 
  sales: 'Sarah').roles
=> [:product_owner]
Please note, that :sales was filtered out, like any would have been except :product_owner, :scrum_master or :developer.
The Hash filtering logic is likely supposed to be repeated. And that is why extending the Hash is plausible.
Ruby on Rails already has in their ActiveSupport gem. The Hash#slice does exactly filter a Hash for keys. So the example in Ruby On Rails would rather look like:
class Team
  def initialize name, roles={}
    @name = name
    @roles = roles.slice :product_owner, :scrum_master, :developer
  end

  def roles
    @roles.keys
  end
end
Team.new('Scrum', product_owner: 'Alice', 
  sales: 'Sarah').roles
=> [:product_owner]
Furthermore Hash#slice! even replaces the hash itself with the given keys. But beware it returns a hash with the removed key/ value pairs.
Further articles of interest:

Supported by Ruby 2.1.1 and Ruby on Rails 4.1.8

Sonntag, 11. Januar 2015

Customize the Rails FormBuilder!

Tolerating as less as possible Ruby logic in the Ruby on Rails views is a basic pattern.
But instead of putting the logic into a Helpers method or Decorator class, moving it into a customized FormBuilder is worth a consideration.
Especially when it:
  1. is tied to a form
  2. is repeated
  3. generates tags (or even multi tag widgets)
Lots of Ruby on Rails views suffer from Ruby blocks with only logic inside (generating the over and over same HTML tag structure) or iterations like:
<% form_for @recipe do |f| %>
  <% (1..10).each do |rating| %>
    <%= f.radio_button :rating, rating %>
    <%= f.label "rating_#{rating}", rating %>
  <% end %>
<% end %>
What if the view could be refactored to:
<% form_for @recipe, builder: Forms::CollectionFormBuilder do |f| %>
  <%= f.labeled_radio_button_group 1..10, :rating %>
<% end %>
Please note the defined option builder:, pointing to the customized FormBuilder.
The better readability is obvious, aside from the less coding. It can be achieved by creating a new class (collection_form_builder.rb) in lib/forms:
module Forms
  class CollectionFormBuilder < ActionView::Helpers::FormBuilder
    def labeled_radio_button_group collection, method, options={}
      collection.inject(''.html_safe) { |html, value|
        checked = object.send(method).eql? value
        options[:id] = "#{method}_#{value}"
        html += @template.radio_button_tag("#{@object_name}[#{method}]", value, checked, options) + 
        @template.label_tag(options[:id], value)
      }   
    end 
  end 
end
by inheriting from ActionView::Helpers::FormBuilder. Thus some instance variables stated by FormBuilder#form_for are available:
  1. @object (the object assigned to form_for itself, like @recipe)
  2. @object_name (the objects name, like "recipe")
  3. @template (the current view (an instance of ActionView::Base); this object provides all methods available in your view)
  4. @options (the options assigned to form_for)
  5. @proc (the block assigned to form_for)
The @template object is coupled with concat (for output) and @proc (which provides the binding from your view). And it provides access to all standard ActionView::Base helper methods, including the custom helper methods (e.g. defined in ApplicationHelper). Furthermore partials can be rendered with @template:
@template.render partial: "fancy_widget", 
                 locals:  { object: @object }
Besides overwriting existing FormBuilder methods can make sense:
module Forms
  class LabeledFormBuilder < ActionView::Helpers::FormBuilder
    def check_box method, options={}, checked_value="1", unchecked_value="0"
      text = options.delete :text
      @template.content_tag(:label) {
        super(method, options, checked_value, unchecked_value) +
        (text or checked_value).to_s.html_safe
      }
    end
  end 
end
which generates the typical check box tag embraced by a label tag:
<% form_for @recipe, builder: Forms::LabeledFormBuilder do |f| %>
  <%= f.check_box :published, text: 'Published', id: nil %>
<% end %>
resulting in HTML:

Further articles of interest:

Supported by Ruby 2.1.1 and Ruby on Rails 4.1.8

Sonntag, 4. Januar 2015

Splat in Ruby method parameters!

Some methods have to deal with collections. The method definition for assigning a collection should not look like:
class Recipe
  def initialize ingredients=[]
    @ingredients = ingredients
  end
end
because sending the message then is as awful as:
Recipe.new ['Banana', 'Chocolate', 'Almonds']
or even worse:
Recipe.new ['Banana']
But the splat (*) operator in Ruby can solve it. The code can be refactored to:
class Recipe
  def initialize *ingredients
    @ingredients = ingredients.flatten.sort
  end

  def ingredients
    @ingredients.join(', ')
  end
end
and sending the message again:
recipe = Recipe.new 'Banana', 'Chocolate', 'Almonds'
recipe.ingredients
=> "Almonds, Banana, Chocolate"
or assigning just one object:
Recipe.new 'Banana'
Even assigning an Array works, because Array#flatten flattens the collection into an one dimensional array:
ingredients = %w(Banana Chocolate Almonds)
recipe = Recipe.new ingredients
=> #<Recipe:0x00000003de66a8 @ingredients=["Almonds", "Banana", "Chocolate"]>
In general the splat (*) operator can be used to split an Array:
one, two, three = *[1, 2, 3]
one
=> 1
two
=> 2
three
=> 3
and to collect an Array:
*numbers = 1, 2, 3
numbers
=> [1, 2, 3]
With the help of the Ruby splat (*) operator method parameters can be variable from zero up to many and handled as an Array internally. No archaic Array assignments anymore. And flatten the collection parameter with Array#flatten increases the flexibility of the API method.
Further articles of interest:

Supported by Ruby 2.1.1