Sonntag, 28. Dezember 2014

Reduce Ruby method parameter complexity!

In Ruby land it is approved that more than 3 method parameters are far too much. Such bloated parameter lists are a code smell. And they smell like a logic overload, which by the way is hard to test. So looking for breaking them apart into smaller pieces is definitely the first step. But even if there is only a small thing going on, there are chances to decrease parameter complexity. A small parameter list is fundamental for a maintainable method. The smaller the parameter list, the less it is likely to change and the greater the chances the method keeps on being stable. Aside from that, a long API parameter list is harder to satisfy and harder to read:
  def foo name, value, state, start_at, end_at, is_new
    # something weird is going on
  end
Never waste time (money) and cheerfulness by trying to deal with code like the above. Refactor it! There are several options, depending on the use case.

1. Deal with parameter objects!

If the method signature consists of parameters, which are likely to be properties of the same object, it is healthy to assign the entire object itself.
class Food
  attr_accessor :name, :kcal, :freshness_date
end

class Consumer < Person
  def eats food_name, kcal, freshness_date
    return if self.allergies.includes?(food_name) or 
      freshness_date.eql?(Date.today)
    self.kcal += kcal
  end
end
can be refactored to:
class Consumer < Person
  def eats food
    return if self.allergies.includes?(food.name) or 
      food.freshness_date < Date.today
    self.kcal += food.kcal
  end
end
With parameter objects, the method signature is way more resistant against changes and therefore more stable in the long run. Furthermore if the logic needs to be reused, the method can be extracted into a module easily.

2. Introduce named parameters!

The more generalized the methods logic or the lower the abstraction level, the more the methods parameter list is likely to consist of optional parameters. Sometimes such methods look like:
class Food
  def initialize name, kcal=0, freshness_date=nil, preservative=nil
    @name = name
    @kcal = kcal
    @freshness_date = freshness_date
    @preservative = preservative
  end
end
Food.new 'Apple', nil, nil, false
which is awkward (since nil is always a bad choice). It should be refactored to:
class Food
  def initialize name, options={}
    @name = name
    @kcal = options[:kcal]
    @freshness_date = options[:freshness_date]
    @preservative = options[:preservative]
  end
end
Food.new 'Apple', preservative: false
Please note the way more expressive object instantiation. Besides adding new optional parameters to the options Hash is easy and does not affect existing code.

3. Replace Parameter with Explicit Methods!

Some use cases do not require a parameter list at all and those parameters should be set explicitly. The object instantiation example again:
class Food
  def initialize name, kcal=0, freshness_date=nil, preservative=nil
    @name = name
    @kcal = kcal
    @freshness_date = freshness_date
    @preservative = preservative
  end
end
Food.new 'Apple', nil, nil, false
but his time defining values with explicit messages:
class Food
  attr_accessor :kcal, :freshness_date, :preservative
  def initialize name
    @name = name
  end
end
apple = Food.new 'Apple'
apple.preservative = false

Further articles of interest:

Supported by Ruby 2.1.1

Sonntag, 21. Dezember 2014

Structure Ruby objects with Structs!

Decomposing fatty degenerated classes into several concerning classes makes sense in any case. Breaking them apart following the single responsibility pattern leads to new classes, each one easy to read, maintain and a pleasure to deal with others.
Sometimes it is very convenient to define one dynamically or it just should be a structure able to receive a few messages. Then the Ruby Struct comes into play.
Creating a Struct object is as easy as:
Struct.new 'Food', :name, :kcal
food = Struct::Food.new 'Apple', 52
=> #<struct Struct::Food name="Apple", kcal=52>
and it has the 2 defined accessors name and kcal:
food.name
=> "Apple"
food.name = 'Pea'
=> "Pea"
food[:kcal] = 57
=> 57
Adding a receiver message goes like:
Struct.new 'Food', :name, :kcal do
  def to_s
    "#{name} (#{kcal})"
  end
end
food = Struct::Food.new 'Apple', 52
food.to_s
=> "Apple (52)"
More practice-focused is inheriting from Struct:
class Food < Struct.new(:name, kcal)
  def to_s
    "#{name} (#{kcal})"
  end
end
and:
food = Food.new 'Apple', 52
food.to_s
=> "Apple (52)"
Whoever argues inheriting from an instance can not be possible: Struct#new returns a class. That is why this also works nice:
Food = Struct.new :name, :kcal
food = Food.new 'Apple'
=> #<struct Food name="Foo", kcal=nil>
food.kcal = 52
A Struct class was assigned to the constant Food. It is possible because classes are just constants.
Please note the difference between the namespaced Struct::Food class in the first example and this Food class.
Structs can be incredible convenient.

Supported by Ruby 2.1.1

Sonntag, 14. Dezember 2014

Create a custom ActiveModel validator!

There are use cases, when the Ruby on Rails standard validators do not satisfy the requirements. Creating a custom validator often times look like:
class Brand < ActiveRecord::Base
  validate :name_likeness
private
  def name_likeness
    like_conditions = name.split.map { |term| 
      self.class.arel_table[:name].matches("%#{term}%") 
    }.inject(&:or)
    return if self.class.where(like_conditions).count.zero?
    errors.add :name, "has already been taken likewise"
  end
end
which ensures the brands name has no term, which already was used in any brands name component.
and using it:
Brand.where("name LIKE ?", "%Fox%")
=> [<Brand id:1, name: 'Fox Media']
brand = Brand.new name: 'Fox Racing'
brand.save
=> false
brand.full_messages_for :name
=> ["Name has already been taken likewise"]
which works but there are various reasons why it should be refactored:
  1. when the custom validation has to be shared on several model classes
  2. because complex validation logic should be extracted into a concerning class
The custom validation logic should be moved into the custom validation class app/validators/likeness_validator.rb:
class LikenessValidator < ActiveModel::EachValidator
  def validate_each record, attribute, value
    like_conditions = value.split.map { |term|
      record.class.arel_table[:name].matches("%#{term}%")
    }.inject(&:or)
    return if record.class.where(like_conditions).count.zero?
    record.errors.add :name, "has already been taken likewise"
  end 
end   
which inherits from ActiveModel::EachValidator and overwrites its validate_each. The logic mostly was copied from the former validating method with the exception of moving the scope from self to record. The former name is passed by the parameter value.
Of course the autoload_paths should be expanded (config/application.rb):
config.autoload_paths += %W["#{config.root}/app/validators/"]
Then the Brand model class can be refactored:
class Brand < ActiveRecord::Base
  validates :name, likeness: true
end
Please note the naming convention: the validation class was named LikenessValidator and is pointed to with the option likeness.
Validating again:
Brand.where("name LIKE ?", "%Fox%")
=> [<Brand id:1, name: 'Fox Media']
brand = Brand.new name: 'Fox Racing'
brand.save
=> false
brand.full_messages_for :name
=> ["Name has already been taken likewise"]
works as expected.
Additional parameters can be assigned like:
class Brand < ActiveRecord::Base
  validates :name, likeness: { min_length: 5 }
end
and used in the custom validation class:
class LikenessValidator < ActiveModel::EachValidator
  def validate_each record, attribute, value
    terms = terms_with_min_length value, options[:min_length]
    return if terms.empty?
    like_conditions = terms.map { |term| 
      record.class.arel_table[:name].matches("%#{term}%") 
      }.inject(&:or)
    return if record.class.where(like_conditions).count.zero?
    record.errors.add :name, "has already been taken likewise"
  end
private
  def terms_with_min_length term, min_length=nil
    terms = term.split
    return terms if min_length.nil?
    term.split.select { |term| 
      term.length >= min_length 
    }
  end
end   
Brand name terms with less than 5 characters satisfy the validation:
Brand.where("name LIKE ?", "%Fox%")
=> [<Brand id:1, name: 'Fox Media']
brand = Brand.new name: 'Fox Racing'
brand.save
=> true

Further articles of interest:

Supported by Ruby 2.1.1 and Ruby on Rails 4.1.8

Sonntag, 7. Dezember 2014

Generate SQL with Arel the Ruby way!

As long as ActiveRecord::Base queries are simple, it is easy to stick to ActiveRecord::QueryMethods like:
Food.where name: 'Peanut butter'
# SELECT "foods".* FROM "foods"  WHERE "foods"."name" = 'Peanut butter'
=> [#<Food id: 1, name: "Peanut butter">]
But what about like-searching by several terms:
class Food < ActiveRecord::Base
  def self.search *terms
    conditions = terms.inject([]) { |conditions, word|
      conditions << "name LIKE ?"
    }.join(" OR ")
    where(conditions, *terms)
  end
end
and querying:
Food.search "Butter", "Apple"
=> [
  #<Food id: 1, name: "Peanut butter">
  #<Food id: 2, name: "Apple juice">
]
works, but is awkward because:
  1. it deals with raw SQL fragments
  2. confuses arguments with question marks
  3. is by far not object oriented
  4. suffers the lack of syntax check
The Food model scope can be refactored easily using Arel:
class Food < ActiveRecord::Base
  def self.search *terms
    conditions = terms.map { |term| 
      arel_table[:name].matches("%#{term}%") 
    }.inject(&:or)
    where(conditions)
  end 
end
The ActiveRecord::Core::ClassMethods#arel_table returns an Arel::Table object. It offers access to all model attributes. For a better understanding: it helps to send to_sql to Arel:
Food.arel_table[:name].matches("%Butter%").to_sql
=> "\"foods\".\"name\" LIKE '%Butter%'"
or the entire example conditions:
%w(Butter Apple).map { |term| 
  Food.arel_table[:name].matches("%#{term}%") 
}.inject(&:or).to_sql
=> "(\"foods\".\"name\" LIKE '%Butter%' OR \"foods\".\"name\" LIKE '%Apple%')"
which is awesome and reveals the power of Arel. No more writing SQL manually required.
It works:
Food.search "Butter", "Apple"
=> [
  #<Food id: 1, name: "Peanut butter">
  #<Food id: 2, name: "Apple juice">
]
The entire flexibility of Arel is documented at Arel API.
Further articles of interest:

Supported by Ruby 2.1.1 and Ruby on Rails 4.1.8

Sonntag, 30. November 2014

Sort your Ruby objects!

Sorting non persisted data collections in Ruby is done by Enumerable#sort or its more flexible companion Enumerable#sort_by. And even persisted data has to be sorted by them in rare cases. A simple example:
%w(Ruby Python Javascript).sort
=> ["Javascript", "Python", "Ruby"]
or
%w(Ruby Python Javascript).sort_by(&:reverse)
=> ["Python", "Javascript", "Ruby"]
But what about a simple class like:
class Food
  attr_accessor :name, :kcal # acronym for kilocalories
  def initialize name, kcal
    @name = name
    @kcal = kcal
  end
end
Assuming the foods collection:
foods = [
  Food.new('Pear', 57), 
  Food.new('Apple', 52), 
  Food.new('Avocado', 164)
]
could be sorted with Enumerable#sort_by:
foods.sort_by(&:name)
=> [
  #<Food @name="Apple", @kcal=52>, 
  #<Food @name="Avocado", @kcal=164>, 
  #<Food @name="Pear", @kcal=57>
]
but can not with not be sorted with Enumerable#sort:
foods.sort
=> ArgumentError: comparison of Food with Food failed
because Ruby expects a sorting method in the Food class definition. Passing the sorting block works:
foods.sort { |a, b| a.name <=> b.name }
=> [
  #<Food @name="Apple", @kcal=52>, 
  #<Food @name="Avocado", @kcal=164>, 
  #<Food @name="Pear", @kcal=57>
]
in which String#<=> satisfies the sorting expectation.
The sorting logic is worth a move into the class definition itself:
class Food
  attr_accessor :name, :kilocalories
  def initialize name, kilocalories # acronym for kilocalories
    @name = name
    @kilocalories = kilocalories
  end

  def <=> other
    name <=> other.name
  end
end
which expects an object responding to a name method, which obviously should return a String. It works like:
foods.sort
=> [
  #<Food @name="Apple", @kcal=52>, 
  #<Food @name="Avocado", @kcal=164>, 
  #<Food @name="Pear", @kcal=57>
]
A more complicated sorting requirements can be defined like:
class Food
  attr_accessor :name, :kcal
  def initialize name, kcal
    @name = name
    @kcal = kcal
  end

  def <=> other
    return -(kcal <=> other.kcal) if name.first.eql? other.name.first
    name <=> other.name
  end
end
which compares the foods by their name, but if the first letter is equal, then sort compares them by their kilocalories but in descending order. Descending is achieved by inverting comparison value, which can be negative, zero or positive.
The rule (whereas 'a' is self and 'b' is the other):
  1. if a < b then return -1
  2. if a = b then return 0
  3. if a > b then return 1
  4. if a and b are not comparable then return nil
The result:
[
  Food.new('Pear', 57), 
  Food.new('Apple', 52), 
  Food.new('Avocado', 164)
].sort
=> [
  #<Food @name="Avocado", @kcal=164>, 
  #<Food @name="Apple", @kcal=52>, 
  #<Food @name="Pear", @kcal=57>
]
Please note that Avocado is before Apple, just because of its higher kilocalories.

Supported by Ruby 2.1.1

Sonntag, 23. November 2014

Modularize ActiveRecord has_many proxy extensions!

There are several reasons for extending ActiveRecord::Associations::ClassMethods#has_many associations (please read Extend has_many association proxy!).
One step further in modularization terms is to put those extension methods into a separate module, because it is a matter of:
  1. reuseability (logic can be reused)
  2. concern (logic is consolidated in a concerning module)
Please note, that moving the methods into a concerning module also means moving it out of the first view. But when it comes to reuseability, there is no alternative.
Imagine the example:
class Recipe < ActiveRecord::Base
  def to_s
    "#{name} (#{time})"
  end
end

class Cook < ActiveRecord::Base
  has_many :recipes do
    def to_s
      map(&:to_s).join(', ')
    end

    def [] term
      where("#{proxy_association.klass.table_name}.name LIKE ?", "%#{term}%")
    end
  end
end
and a use case like:
Cook.first.recipes['cookie'].to_s
=> "Chocolate Chunk Cookies (30), Amish Cookies (60)"
can be refactored by moving both Proxy extension methods into a module:
module HasManyProxyExtension
  module NameSearchableAndHumanizable
     def [] term
      where("#{proxy_association.klass.table_name}.name LIKE ?", "%#{term}%")
    end

    def to_s
      map(&:to_s).join(', ')
    end
  end
end

class Cook < ActiveRecord::Base
  has_many :recipes, 
    extend: HasManyProxyExtension::NameSearchableAndHumanizable
end
and the use case again:
Cook.first.recipes['cookie'].to_s
=> "Chocolate Chunk Cookies (30), Amish Cookies (60)"
is still working with the advantage being able to reuse the module in another class:
class Recipe < ActiveRecord::Base
  has_many :ingredients, 
    extend: HasManyProxyExtension::NameSearchableAndHumanizable
  def to_s
    "#{name} (#{time})"
  end
end

class Ingredient < ActiveRecord::Base
  def to_s
    return name if legal?
    "#{name} (illegal)"
  end
end
and its use case:
Recipe.first.ingredients['as'].to_s
=> "Basil, Sassafras (illegal)"
Imagine, how the model classes would look like, if the logic could not be moved into a module.
Some times it is good choice to extend an association proxy with multiple modules:
module HasManyProxyExtension
  module NameSearchable
     def [] term
      where("#{proxy_association.klass.table_name}.name LIKE ?", "%#{term}%")
    end
  end

  module Humanizable
    def to_s
      map(&:to_s).join(', ')
    end
  end
end

class Cook < ActiveRecord::Base
  has_many :recipes, 
    extend: [HasManyProxyExtension::NameSearchable, HasManyProxyExtension::Humanizable]
end
Of course it still works the same. But It allows deeper modularization and a more versatile combination of modules.
Further articles of interest:

Supported by Ruby 2.1.1 and Ruby on Rails 3.2.17

Sonntag, 16. November 2014

Extend has_many association proxy!

ActiveRecord::Associations::ClassMethods#has_many and its companion ActiveRecord::Associations::ClassMethods#has_and_belongs_to_many in Ruby on Rails are both extendible associations. It is a convenient approach to extend Proxy objects for various reasons:
  1. encapsulates logic which applies to the association
  2. provides more expressive access to associated model objects
  3. is combinable with collection proxy object methods
Assuming the original classes:
class Cook < ActiveRecord::Base
  has_many :recipes
end

class Recipe < ActiveRecord::Base
  def self.named_like name
    where("#{table_name}.name LIKE ?", "%#{name}%")
  end

  def name_with_time
    "#{name} (#{time})"
  end
end
whereas a cook has many recipes.

Encapsulate logic

Getting all recipes as a comma separated String is coded quickly:
Cook.first.recipes.map(&:name_with_time).join(', ')
=> "Chocolate Chunk Cookies (30), Oatmeal Shortbread (45)"
but can be refactored from the reuseability perspective by moving the logic into the Cook association to Recipe:
class Cook < ActiveRecord::Base
  has_many :recipes do
    def to_s
      map(&:name_with_time).join(', ')
    end
  end
end
Now the logic, how to get recipes String does not need to be reproduced any more:
Cook.first.recipes.to_s
=> "Chocolate Chunk Cookies (30), Oatmeal Shortbread (45)"

Increase Expressiveness

Another scenario is to search all the cooks recipes by a term:
Cook.first.recipes.named_like('cookie')
=> [#<Recipe id: 1, name: "Chocolate Chunk Cookies", time: 30>]
is pretty expressive, but can be improved by extending the association once again:
class Cook < ActiveRecord::Base
  has_many :recipes do
    def [] term
      named_like term
    end
  end
end
and sending the message:
Cook.first.recipes['cookie']
=> [#<Recipe id: 1, name: "Chocolate Chunk Cookies", time: 30>]

Combine extensions

Proxy objects extensions also can be combined easily, which makes logic flexible and reusable:
class Cook < ActiveRecord::Base
  has_many :recipes do
    def to_s
      map(&:name_with_time).join(', ')
    end

    def [] term
      named_like term
    end
  end
end
and combining both:
Cook.first.recipes['cookie'].to_s
=> "Chocolate Chunk Cookies (30)"
whereas the chain order matters.
Of course the association proxy extensions also can be combined with other CollectionAssociation methods like:
Cook.first.recipes['cookie'].count
=> 1
which generates a different SQL statements projection part as expected. Accessing the Proxy objects inside the extension is also easy as:
class Cook < ActiveRecord::Base
  has_many :recipes do
    def [] term
      named_like term
    end

    def shallow_copy
      proxy_association.proxy.map(&:dup)
    end
  end
end
The message receiver Cook#shallow_copy simply clones the associated objects:
Cook.first.recipes['cookie'].shallow_copy
=> [#<Recipe name: "Chocolate Chunk Cookies", time: 30>]
Please note the cloned recipe has no ID, since it is a new record.
The collection proxy object provides some more helpful accessors like ActiveRecord::Associations::HasManyAssociation#owner and ActiveRecord::Associations::HasManyAssociation#reflection
Further articles of interest:

Supported by Ruby 2.1.1 and Ruby on Rails 3.2.17

Sonntag, 9. November 2014

Respond with JSON using Rabl gem!

JSON format is the de facto standard especially compared to XML. Nowadays controllers responding with JSON is no novelty. Often times a controller responding with JSON looks as simple as:
class IngredientsController < ApplicationController
  respond_to :json

  def index
    respond_with Ingredients.all
  end
end
and requesting it:
curl http://localhost:3000/ingredients.json
=> [
  {"id":1,"created_at":"2014-08-09T19:08:44Z","name":"Basil","illegal":false},
  {"id":2,"created_at":"2014-08-09T19:08:56Z","name":"Ginger","illegal":false},
  {"id":3,"created_at":"2014-11-09T19:13:38Z","name":"Sassafras","illegal":true}
]
which JSONifies the found Ingredient objects and responds them in a very concise manner. It works fine for simple use cases.
But oftentimes use cases get more complex and then a primitive JSON mapping does not satisfy the requirements adequate. For example, when:
  1. the collection response is tremendous and responding only the relevant object attributes makes a huge payload difference
  2. the client receiver Javascript API expects a dedicated JSON object signature (e.g autocompleters often expect 'id' and 'name')
  3. the responding JSON objects require access to custom ActiveRecord methods
then hacking around ActiveRecord#to_json or even ActiveRecord#as_json has its limitation and is rarely convenient. Besides it is a view thing (just another representation of the objects) and requires templating.
Then the Rabl gem comes into play. It is a templating module for JSON objects, which provides the required flexibility.
It is easy included into the Ruby on Rails project (Gemfile):
gem 'rabl'
For example a new requirement wants an autocompleter to list the searched ingredients by their name with acronym in brackets. A solution could be refactoring the controller:
class IngredientsController < ApplicationController
  respond_to :json

  def index
    @ingredients = Ingredients.search params[:search]
    respond_with @ingredients
  end
end
and extending the model:
class Ingredient < ActiveRecord::Base
  def self.search term
    where("#{table_name}.name LIKE :term OR #{table_name}.description LIKE :term", { term: "%#{term}%" })
  end
end
Finally the view (ingredients/index.json.rabl):
collection @ingredients, object_root: false
attributes :id
node(:name) { |ingredient|
  text = ingredient.name 
  text << " (illegal)" if ingredient.illegal?
  text
}
needs some explanation. At first the instance variable @ingredients contains the ingredients collection. The default root node can be removed by setting the option object_root: false.
The required attributes are defined by assigning them to attributes and custom nodes can be defined by passing a block to node.
There are more options and the Rabl API is way more flexible when it comes to child nodes, gluing attributes, partials, inheritance, deep nesting, caching etc.
Requesting the ingredients:
curl http://localhost:3000/ingredients.json?search=as
=> [
  {"id":1,"name":"Basil"},
  {"id":3,"name":"Sassafras (illegal)"}
]
Responding to a request for a specific object could look like:
class IngredientsController < ApplicationController
  respond_to :json

  def show
    @ingredient = Ingredients.find params[:id]
    respond_with @ingredient
  end
end
and its view (ingredients/show.json.rabl):
object @ingredient
attributes id: :id, to_s: :title
child :foods, object_root: 'meal' do
  attribute :name
end
Requesting it:
curl http://localhost:3000/ingredients/1.json
=> {"ingredient":{"title":"Basil","foods":[
    {"meal":{"name":"Garlic Basil Shrimp"}},
    {"meal":{"name":"Basil and Lime Sorbet"}}
  ]
}}

Supported by Ruby 2.1.1 and Ruby on Rails 3.2.17

Sonntag, 2. November 2014

Parse XML in Ruby with Nokogiri gem!

The Ruby gem 'Nokogiri' is the quasi standard for parsing XML and HTML in the Ruby community.
The official Nokogiri web page explains how to install it on various platforms.
An XML file like the catalog.xml:



  
  
  
  
  

can be loaded and parsed like:
file_path = '/usr/share/xml/docbook/schema/dtd/catalog.xml'
xml = Nokogiri::XML(File.read file_path)
=> #<Nokogiri::XML::Document:0xfda908 name="document"...>
There are also several XML/ HTML parse options available, for example eliminating all blank nodes:
xml = Nokogiri::XML File.read(file_path), &:noblanks
=> #<Nokogiri::XML::Document:0xfda908 name="document">
The returned Nokogiri object provides a lot ways of accessing the XML nodes.

Basic Ruby API

The object can be grasped with pure Ruby like:
xml.children.children.select { |node| 
  node.name.eql? 'system' 
}.map{ |node| 
  node.attributes["systemId"].value 
}
=> ["http://oasis-open.org/docbook/xml/4.1/docbookx.dtd", 
"http://docbook.org/xml/4.1/docbookx.dtd"]
which often times is cumbersome and verbose. That is why there are other APIs.

Basic XPath API

One of them is XPath:
xml.xpath("//xmlns:catalog/xmlns:system/@systemId")
=> [#<Nokogiri::XML::Attr:0xf4ea20 name="systemId" value="http://oasis-open.org/docbook/xml/4.1/docbookx.dtd">, 
#<Nokogiri::XML::Attr:0xf4e110 name="systemId" value="http://docbook.org/xml/4.1/docbookx.dtd">]
which has to be combined with Ruby to get the values too:
xml.xpath("//xmlns:catalog/xmlns:system/@systemId").
  map(&:value)
=> ["http://oasis-open.org/docbook/xml/4.1/docbookx.dtd", 
"http://docbook.org/xml/4.1/docbookx.dtd"]
Dealing with namespaces in many use cases is annoying and can be removed:
xml.remove_namespaces!.
  xpath("//catalog/system/@systemId").map(&:value)
=> ["http://oasis-open.org/docbook/xml/4.1/docbookx.dtd", 
"http://docbook.org/xml/4.1/docbookx.dtd"]
The entire XPath reference is documented at w3school.

Basic CSS API

The third kind of accessing the XML node tree is CSS. The full CSS selector reference also is documented at w3school, but receiving XML nodes works like:
xml.css("catalog > system")
=> [#<Nokogiri::XML::Element:0xf4ea84 name="system" attributes=[
  #<Nokogiri::XML::Attr:0xf4ea20 name="systemId" value="http://www.oasis-open.org/docbook/xml/4.1/docbookx.dtd">
]>, 
#<Nokogiri::XML::Element:0xf4e174 name="system" attributes=[
  #<Nokogiri::XML::Attr:0xf4e110 name="systemId" value="http://docbook.org/xml/4.1/docbookx.dtd">
]
With the CSS API only the nodes can be grasped. When dealing with their attributes is required Ruby API comes into play:
xml.css("catalog > system").map{ |node| 
  node.attributes['systemId'].value 
}
=> ["http://oasis-open.org/docbook/xml/4.1/docbookx.dtd", 
"http://docbook.org/xml/4.1/docbookx.dtd"]


Nokogiri can handle HTML documents as well.
Grasping the home page document from Nokogiri with curl (read Tell shell scripting apart in Ruby!) and finding the text of the first tutorials link is easy as:
html = Nokogiri::HTML(%x[curl http://www.nokogiri.org/])
html.css('.page ol li a').first.text

Further articles of interest:

Supported by Ruby 2.1.1

Sonntag, 26. Oktober 2014

Take a look at Ruby percentages

There are some Ruby %-notations which emerge as nice shortcuts. Those literals are Perl inspired.
Please note, that indeed all non-alpha-numeric delimiters are allowed, but it is highly recommended to use bracket delimiters for readability and unescaping reasons, like:
  1. ()
  2. []
  3. {}
  4. <>

1. Non-interpolated String

allows unescaping and string notation:
%q(Ruby string (syntax) is "pretty" flexible)
=> "Ruby string (syntax) is \"pretty\" flexible"
Please compare with the String result.

2. Interpolated String

allows flexible interpolation:
choosen_language = "Ruby"
%Q(#{choosen_language} string (syntax) is "pretty" flexible)
=> "Ruby string (syntax) is \"pretty\" flexible"
and there is also an even shorter literal. % (percentage) alone is the default for an interpolated String:
choosen_language = "Ruby"
%(#{choosen_language} string (syntax) is "pretty" flexible)
=> "Ruby string (syntax) is \"pretty\" flexible"

3. Non-interpolated Symbol

is maybe unusual:
%s(ruby)
=> :ruby
But dealing with arbitrary characters like spaces and dashes also works:
%s(ruby is awesome)
=> :"ruby is awesome"
and is more concise and idiomatic than:
"ruby is awesome".to_sym
=> :"ruby is awesome"

4. Non-interpolated String Array

is already quite popular:
%w(Ruby Python Clojure)
=> ["Ruby", "Python", "Clojure"]
The Array elements are separated by whitespace.

5. Interpolated String Array

is more flexible:
choosen_language = "Ruby"
%W(#{choosen_language} Python Clojure)
=> ["Ruby", "Python", "Clojure"]
The Array elements also are separated by whitespace.

6. Non-interpolated Symbol Array

maybe is less known but analog to its String companion:
%i(ruby python clojure)
=> [:ruby, :python, :clojure]

7. Interpolated Symbol Array

is also equivalent to its String mate:
choosen_language = "ruby"
%I(#{choosen_language} python clojure)
=> [:ruby, :python, :clojure]

8. Interpolated shell command

is pretty helpful for shell scripting:
language = "ruby"
%x(#{language} --version)
=> "ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-linux]\n"
language = "nodejs"
%x(#{language} --version)
=> "v0.10.32\n"
Although there are also other Ruby shell scripting approaches (Please read Tell shell scripting apart in Ruby!)

9. Interpolated regular expression

can be used with flags after the closing delimiter
disliked_language = "Java"
string = %Q(#{disliked_language} helps to solve my problems.)
regexp = /#{disliked_language}/i
string.gsub(regexp, 'Ruby')
The literal briefing:
Literal Meaning
%qNon-interplated String
%QInterpolated String
%sNon-interpolated Symbol
%wNon-interpolated String Array
%WInterpolated String Array
%iNon-interpolated Symbol Array
%IInterpolated Symbol Array
%xInterpolated Shell command
%rInterpolated regular expression

Further articles of interest:

Supported by Ruby 2.1.1

Sonntag, 19. Oktober 2014

Create a simple Ruby rake task!

Some times simple tasks around the application need to be done. They are not a primary part, but belong to the application. Those tasks are called automated tasks (e.g. automated built system). Rake is such task system based on the make file idea, but scripted in Ruby.
A really simple rake task skeleton in lib/tasks/test.rake looks like:
namespace :awesome do
  desc "Awesome Ruby does awesome things."
  task :ruby do |t| 
    puts "Ruby is awesome!"
  end 
end
and only consists of a task and its description. It can be listed with:
rake -T | grep ruby
=> rake awesome:ruby   # Awesome Ruby does awesome things.
Calling it in bash:
rake awesome:ruby
=> Ruby is awesome!
A little more reasonable rake task could be an automated version system merge of a branch back into the trunk.
Assuming GIT was set up with those configurations:
git config user.name "trinibago"
git config --global credential.helper /usr/share/doc/git/contrib/credential/gnome-keyring/git-credential-gnome-keyring
git config --global push.default current
which configures my github user name, my credentials for the account (prevents account prompts) and the current checked out branch to be the one to push to remotely.
The git rake task in lib/tasks/git.rake:
namespace :git do
  desc "GIT merges branch back into master"
  task :merge, :message do |t, args|
    safe_task do
      branches = %x[git branch]
      current_branch = branches.split("\n").map(&:strip).
        detect { |x| x.match(/^*\s/) }.gsub(/^[*]\s/, '') 
      %x[git commit -a -m "#{args[:message]}"]
      # pushes the current branch changes to the remote
      %x[git push]
      # switches back to master
      %x[git checkout master]
      # merges the current branch
      %x[git merge "#{current_branch}"]
      # pushes the merged mater changes to the remote
      %x[git push]
    end 
  end 
end

private
  def safe_task
    yield
  rescue Errno::ENOENT => e
    puts "Task couldn't be executed.\n#{e.message}"
  end 
demands some explanation.
  1. all parameters are listed in args as a hash
  2. other Ruby functions can be called (like the safe_task, which wraps the exception handling)
  3. %x literal is a Ruby system call (read Tell shell scripting apart in Ruby!)
  4. the result of 'git branch' is parsed for getting the current branch name
  5. simple git commands processed sequentially
In console the task can be invoked by:
rake git:merge["Hottest fix ever"]
=> Counting objects: 13, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 417 bytes | 0 bytes/s, done.
Total 5 (delta 4), reused 0 (delta 0)
To https://github.com/trinibago/nested_set
 * [new branch]      hotfix -> hotfix
Switched to branch 'master'
Everything up-to-date
Rake tasks can be simple helper tools in daily life and also are combinable.
Further articles of interest:

Supported by Ruby 2.1.1 and Ruby on Rails 3.2.19

Sonntag, 12. Oktober 2014

Tell shell scripting apart in Ruby!

Ruby scripting for the shell provides multiple ways, depending on the use case.

Kernel#system

The simplest way to fire a shell command in a Ruby script is to send a message to Kernel#system.
In a nutshell:
  1. the command is assigned as a String
  2. the first parameter is the command itself and all following string parameters are the arguments
  3. executes the command in a subshell
  4. is a blocking operation (waits until the result of operation completes)
  5. returns true (for zero exist status), false (for non zero exit status) or nil (if command execution fails)
  6. The commands result is not available for further processing
  7. captures exceptions raised from the child process
  8. the error status (exception) is available in $?, which returns a Process::Status object
Some examples:
system("find *.rb")
# script.rb
# => true
file_name = "script"
system("find", "#{file_name}.rb")
# script.rb
# => true
system("find", "*.rb")
# find: "*.rb": No such file or directory
# => false
$?
# => #<Process::Status: pid 4438 exit 1>
Please note the third command (and compare with the first command): Assigning wild card as a parameter does not work properly.
Kernel#system is great for simple system calls, if the result (e.g. the found files list) is not needed for further processing.

Kernel#exec

Kernel#exec works similar to Kernel#system, with an essential difference: it ends the current process by running the given external command. Running the script.rb:
exec("find *.rb")
puts "End"
will print out script.rb, but not "End". Another example, using IRB:
christian@Trinidad:~$ irb
2.1.1 :001 > exec("date")
Sun, 12 Oct 2014 06:40:23 CEST
christian@Trinidad:~$
exits IRB (the current process), processes the command and returns to bash.

%x() literal

An interpolated shell command can be achieved with the %x() literal as an alternative to the backtick style.
In a nutshell:
  1. the command can be as assigned as a String or even without string notation
  2. executes the command in a subshell
  3. is a blocking operation (waits until the result of operation completes)
  4. returns the command result
  5. raises exception caused by the child process error
  6. the error status (exception) is available in $?, which returns a Process::Status object (with qualified exit status)
Some examples:
%x[find *.rb]
# => "script.rb"
file_name = "script"
%x["find #{file_name}.rb"]
# => script.rb
Time.parse %x[date].chop
# => 2014-10-10 02:23:10 +0200
%x[foo]
# => Errno::ENOENT: No such file or directory - foo
$?
# => #<Process::Status: pid 5052 exit 127>
for comparison reasons, the same stuff with the backtick notation:
`find *.rb`
# => "script.rb"
file_name = "script"
`find #{file_name}.rb`
# => script.rb
Time.parse `date`.chop
# => 2014-10-10 02:23:10 +0200
`foo`
# => Errno::ENOENT: No such file or directory - foo
$?
# => #<Process::Status: pid 5055 exit 127>
The backtick notation is widely used but can be mixed up with String and therefore is not as readable (and intentional) as the %x literal.

Open3#popen3

Another level of granularity is the Open3#popen3.
It allows to deal with the input, output, error and even the wait thread.
  1. the command is assigned as a String
  2. executes the command in a subshell
  3. can be a non blocking operation (run other commands while processing the thread)
  4. full control over the thread
  5. full control over the stdin, stdout and stderr stream
A script.rb could look like:
stdin, stdout, stderr, wait_thr = Open3.popen3('ping www.google.com -c 3')
puts "Thread alive? #{wait_thr.alive?}"
puts "Some calculation: #{1 + 1}"
puts "Output: " + stdout.read
puts "Thread alive? #{wait_thr.alive?}"
# => Thread alive? true
# Some calculation: 2
# PING www.google.com (74.125.136.103) 56(84) bytes of data.
# 64 bytes from ea-in-f103.1e100.net (74.125.136.103): icmp_seq=1 ttl=46 time=26.8 ms
# 64 bytes from ea-in-f103.1e100.net (74.125.136.103): icmp_seq=2 ttl=46 time=24.7 ms
# 64 bytes from ea-in-f103.1e100.net (74.125.136.103): icmp_seq=3 ttl=46 time=23.2 ms
# --- www.google.com ping statistics ---
# 3 packets transmitted, 3 received, 0% packet loss, time 2001ms
# rtt min/avg/max/mdev = 23.229/24.913/26.804/1.477 ms
# Thread alive? false
Please note, that the stdout.read output waited until the thread was successfully ended. That is why there is 2 seconds gap between the calculations output and the stdout.read.
All 3 stdxxx are IO objects. The fourth wait_thr is a Thread object.
Open3#popen3 is the way to deal with system calls, when advanced processing is needed. Especially the full control over its streams is very powerful.
Further articles of interest:

Supported by Ruby 2.1.1

Sonntag, 5. Oktober 2014

Remove boolean parameters from your Ruby API!

Boolean parameters in method definitions are not a good choice for various reasons. They:
  1. are not readable
  2. duplicate code or responsibility inside and outside the method
There are alternatives to expecting true/ false. Let us assume a Ruby class like:
class Food
  def self.order vegetarian=false
    return "Vegetarian food" if vegetarian
    "Conventional food"
  end
end
The original code works so far, but using it is no laughing matter:
Food.order true # => "Vegetarian food"
Food.order # => "Conventional food"
What does "Food.order true" express? Does it mean "The Food order is no lie and is meant seriously"? TrueClass and FalseClass are not expressive in no way.
Even following the expressive boolean pattern (Express boolean parameters the Ruby way!) is not the best choice:
Food.order :vegetarian # => "Vegetarian food"
Food.order # => "Conventional food"
That is a little nicer, but it would be great to make even this work:
Food.order :conventional # => "Conventional food"
Every time the API is yours you have the choice to make it work great.
Use Enums instead of Booleans!
The original class should be refactored and expect Enum like:
class Food
  def self.order type=:conventional
    types = %i(conventional vegetarian)
    fail "Invalid Food type." unless types.member? type
    return "Conventional food" if type.eql? :conventional
    "Vegetarian food"
  end
end
and then:
Food.order :vegetarian # => "Vegetarian food"
Food.order :conventional # => "Conventional food"
Food.order :something_else # => RuntimeError: 
# Invalid Food type.
# Must one be of :conventional or :vegetarian.
The Enum method definition directs to a strict parameter expectation, which prevents API misinterpretations.
Although it still couples code or responsibility from outside and inside the method, there is another pro for Enums. It is way more extensible than boolean parameters can be.
A new requirement wants vegan food to be added:
class Food
  def self.order type=:conventional
    types = %i(conventional vegetarian vegan)
    fail "Invalid Food type." unless types.member? type
    case type
    when :vegetarian
      "Vegetarian food"
    when :vegan 
      "Vegan food"
    else "Conventional food"
    end
  end
end
Forgive the usage of a case statement for simplicity reasons.
Every time a new type of food has to be added the method can be changed without hurting the message senders, whereas boolean parameters will ruin the public API.
Further articles of interest:

Supported by Ruby 2.1.1

Sonntag, 28. September 2014

Express boolean parameters the Ruby way!

At first: prevent using boolean parameters in method definitions!
In Ruby land boolean parameters are outlawed. And there is a reason for. They:
  1. are not readable
  2. duplicates code or responsibility inside and outside the method
1.) Boolean parameters are no readable, because they do not express which meaning is behind true or false.
2.) And they duplicate the condition, which led to the boolean parameter inside and outside the method. The reason for having a boolean parameter often is the wish to generalize the message (method). But the wish is insidious, because it moves the arisen condition out of the method and repeats checking the boolean parameter inside the method. This fact couples the message (method) to its callers (code coupling).
A solution often is making the method private and revealing 2 public message points instead, calling the private method.
Since there are APIs expecting boolean parameters for various reasons, there is also a nice way to deal with it. For example the Ruby on Rails helper method ActionView::Helpers::FormTagHelper#check_box_tag with the method signature:
check_box_tag(name, value = "1", checked = false, 
  options = {})
expects a boolean parameter as the third.
The original code generates a HTML check box tag being unchecked:
check_box_tag("Permitted", "1", true, id: "permitted")
which is unreadable in terms of the boolean parameter. What does "true" mean? You only know, if you know the API method signature...
But it can be refactored to:
check_box_tag("Permitted", "1", :checked, id: "permitted")
which solves the readability issue, because it reveals that the HTML check box tag will be checked, since all objects except FalseClass and NilClass are true and therefore a Symbol is too.
Improving the readability by assigning expressive symbols/ strings is a solution for all APIs expecting a FalseClass boolean parameter by default, which is common practice.
Further articles of interest:

Supported by Ruby 2.1.1 and Ruby on Rails 3.2.17

Sonntag, 21. September 2014

5 Ruby shots!

1. Extract regular expression matches quickly!

String#match is the typical message receiver for examining String patterns. With the help of regular expressions the Stings patterns can be matched/ found like:
email = "chris@ruby.de"
email.match(/@((?:[-a-z0-9]+\.)+[a-z]{2,})/)[1]
can be refactored to:
email[/@((?:[-a-z0-9]+\.)+[a-z]{2,})/, 1]
which looks much cleaner. With Strings being a sequence (array) of characters in mind, the logic is even more compelling.
The API String#[] documentation reveals even more examples.

2. Use the method block shortcut!

Methods and especially enumerations and their blocks can look way too extensive in simple use cases, for example:
[1, 2, 3 ].map { |number| number.to_s } #=> ["1", "2", "3"]
[1, 2, 3 ].select { |number| number.odd? } #=> [1, 3]
Inside the block there is only one message sent to the iterated Fixnum object, without any parameters. The logic is super simple and that is why Ruby offers a shortcut for such. Please compare the examples with:
[1, 2, 3 ].map(&:to_s) # => ["1", "2", "3"]
[1, 2, 3 ].select(&:odd?) # => [1, 3]
Use the shortcut for all iterators, with the receiver (iterated object) only receiving one message (method call) inside the block and the message (method call) expecting any parameters.
It is implemented by passing the message (method call) as a symbol and an unary ampersand (&).
Please note that the shortcut is not an enumerator thing only. It can be used for every method expecting a block.

3. Explode enumerables!

There are methods having a variable length of parameters. Array#values_at is such a candidate. For example getting objects at specific indexes:
[1, 2, 3, 4, 5].values_at(0, 4) # => [1, 5]
works fine as long as the indexes are known. But if the number of indexes or the indexes themselves are calculated, there is no other option than dealing with an array and exploding it to a parameter list:
# indexes = [0, 4]
[1, 2, 3, 4, 5].values_at(*indexes) # => [1, 5]
In the case the sequence of numbers also is calculated, it can be achieved by exploding a range like:
first = 1
last = 5
numbers = *(first..last) # => [1, 2, 3, 4, 5]
indexes = [0, 4]
numbers.values_at(*indexes) # => [1, 5]
... so powerful.

4. Rescue without verbosity!

The verbose way of exception handling looks like:
def slice_it
  begin
    "Ruby".slice
  rescue ArgumentError => e
    $stderr.puts "Read the API documention of String#slice.
      Message: '#{e}'"
  end
end
but it can be less verbose without the explicit begin/ end block style, because method definitions are implicitly also exception blocks:
def slice_it
  "Ruby".slice
rescue ArgumentError => e
  $stderr.puts "Read the API documention of String#slice.
    Message: '#{e}'"
end

5. Identify the Hash values with non Strings/ Symbols!

Associative arrays (aka Hash) are key/ value stores in their basic meaning. The keys usually are symbols or strings. For example:
{ language: 'Ruby', 'version' => 2.1 }
Sometimes it is a better idea to have meaningful keys. Imagine a cache store for all people grouped by their birthday:
people = Person.all.group_by(&:birthday)
# => { Sat, 21 Sep 1996 => [#<Person 1>, #<Person 2>], 
Fri, 19 Apr 1996 => [#<Person 3>] }
which can be accessed easily:
people[18.years.ago]
# => [#<Person 1>, #<Person 2>]
In this case the keys are Date objects, but Hash keys can be any kind of objects.

Supported by Ruby 2.1.1

Sonntag, 14. September 2014

Load your ActiveRecord objects eagerly!

Eager loading associated ActiveRecord::Base model objects by ActiveRecord::QueryMethods#includes is a common practice for Ruby on Rails developer. Especially when the resulting query is generated dynamically on run time depending on unknown factors.
The nice thing about it: it decides whether it generates one huge SQL join query or multiple small queries for performance reasons. The decision is based on the selection part of the SQL query. If the selection refers to one of the joined tables, the SQL query has to be the huge SQL chunk with all its joins and attributes aliasings, which is a parsing nightmare.
That is why the default approach for includes is preload, with its small and fast querying (read Preload your ActiveRecord objects!). Besides each of the small queries are likely a candidate for query caching and therefore a performance improvement.
For example the original code:
class Category < ActiveRecord::Base
  has_many :foods
end

class Food < ActiveRecord::Base
  belongs_to :category
end
and eager loading (aka preloading) the categories and their associated foods by searching the food name:
@categories = Category.includes(:foods).
  where("foods.name LIKE :term", { term: '%milk%' })
also generates the SQL:
SELECT "categories"."id" AS t0_r0, 
"categories"."name" AS t0_r1, 
"categories"."created_at" AS t0_r2, 
"categories"."updated_at" AS t0_r3, 
"foods"."id" AS t1_r0, 
"foods"."name" AS t1_r1, 
"foods"."created_at" AS t1_r2, 
"foods"."updated_at" AS t1_r3, 
"foods"."category_id" AS t1_r4, 
"foods"."description" AS t1_r5 
FROM "categories" 
LEFT OUTER JOIN "foods" 
  ON "foods"."category_id" = "categories"."id" 
WHERE (foods.name LIKE '%milk%')
Please note that ActiveRecord::QueryMethods#includes generates 1 SQL query joining both tables by a LEFT JOIN and the projection part contains already a lot of aliased attributes.
An easy step to improve the codes intention is to replace includes by eager_load like:
@categories = Category.eager_load(:foods).
  where("foods.name LIKE :term", { term: '%milk%' })
The generated SQL is exactly the same:
SELECT "categories"."id" AS t0_r0, 
"categories"."name" AS t0_r1, 
"categories"."created_at" AS t0_r2, 
"categories"."updated_at" AS t0_r3, 
"foods"."id" AS t1_r0, 
"foods"."name" AS t1_r1, 
"foods"."created_at" AS t1_r2, 
"foods"."updated_at" AS t1_r3, 
"foods"."category_id" AS t1_r4, 
"foods"."description" AS t1_r5 
FROM "categories" 
LEFT OUTER JOIN "foods" 
  ON "foods"."category_id" = "categories"."id" 
WHERE (foods.name LIKE '%milk%')
But if you want to reveal which eager loading approach will happen, you should stick to eager_load, because that makes clear, you kow:
  1. a huge join query will be generated
  2. the query will not be cached
  3. there is a reference of the query selection/ aggregation/ order part to at least 1 join table
Otherwise you point out that you do not know anything about how the ActiveRecord objects are loaded eagerly.
Further articles of interest:

Supported by Ruby 2.1.1 and Ruby on Rails 3.2.17

Sonntag, 7. September 2014

Preload your ActiveRecord objects!

Eager loading associated ActiveRecord::Base model objects is always a good choice. A lot Ruby on Rails developer take advantage of the ActiveRecord::QueryMethods#includes and do not care anymore. A better approach is to care.
For example the original associations:
class Category < ActiveRecord::Base
  has_many :foods
end

class Food < ActiveRecord::Base
  belongs_to :category
end
and eager loading (aka preloading) the categories and their associated foods:
@categories = Category.includes(:foods).all
generates a SQL like:
SELECT "categories".* FROM "categories"
SELECT "foods".* FROM "foods" WHERE "foods"."category_id" IN (1, 2, 3)
Please note that ActiveRecord::QueryMethods#includes generates 2 SQL queries. The database tables categories and foods are not joined together.
And that is exactly the same what ActiveRecord::QueryMethods#preload does. That is why:
@categories = Category.preload(:foods).all
also generates the SQL:
SELECT "categories".* FROM "categories"
SELECT "foods".* FROM "foods" WHERE "foods"."category_id" IN (1, 2, 3)
But beware, the selection conditions are not allowed to refer to the preloaded association table attributes.
So something like:
@categories = Category.preload(:foods).where("foods.name LIKE '%corn%'").all
will raise an SQL exception:
SQLException: no such column: foods.name: SELECT "categories".* FROM "categories"  WHERE (foods.name LIKE '%corn%')
But as long as the query is simple and is intended to keep on being simple, it totally makes sense to prefer ActiveRecord::QueryMethods#preload to ActiveRecord::QueryMethods#includes.
Furthermore it is more intentional about what the code is doing. And that is always a win.
Further articles of interest:

Supported by Ruby 2.1.1 and Ruby on Rails 3.2.17

Sonntag, 31. August 2014

Define polymorphic ActiveRecord model association!

If you feel yourself in the position that one of your ActiveRecord models belongs to more than one other model, you are facing a polymorphic association.
Polymorphism is the provision of a single interface to entities of different types.
A polymorphic association saves you from:
  1. multiple alike tables and models (and therefore logic repetition)
  2. extensive meaningless foreign key attributes
  3. abuse of STI pattern
The original codes reveals a simple association between Comment and Article:
class Comment < ActiveRecord::Base
  belongs_to :article
end

class Article < ActiveRecord::Base
  has_many :comments
end
If also the Author should be commentable, adding a second foreign key attribute author_id is not a good choice (one of the foreign key attribute is meaningless in every case and it is horrible to validate both associations not interfering each other).
Adding a second model e.g. AuthorComment also is no option for duplication reasons.
On the other hand converting the association to a polymorphic association is fairly easy:
1.) rename the foreign key attribute article_id to the more abstract commentable_id and migrate it:
rename_column :comments, :article_id, :commentable_id
2.) add a new attribute commentable_type and migrate it:
add_column :comments, :commentable_type, :string
The attribute commentable_type is for defining the name of the associated class like Article and Author as string. It should always end with '_type'. Otherwise you have to configure it by the option :foreign_type on the belongs_to association.
3.) the model is ready for the polymorphic association:
class Comment < ActiveRecord::Base
  belongs_to :commentable,
    polymorphic: true
end
4.) multiple models can use it:
class Article < ActiveRecord::Base
  has_many :comments,
    as: :commentable
end

class Author < ActiveRecord::Base
  has_many :comments,
    as: :commentable
end
The models are based on the ERM:

Supported by Ruby 2.1.1 and Ruby on Rails 3.2.17

Sonntag, 24. August 2014

Singularize resource routes, if it is singular!

In most cases plural routes (read Simple RESTful Ruby on Rails routes) are needed to deal with the resources. But sometimes it makes sense to have only a singular resource routing.
Whenever a resource is singular (like Singletons) or singular in the current context, its routes should be singular as well. Reasons are:
  1. Expressiveness (to express the resource is singular)
  2. Less routes (singular resources have no index route for returning collections)
  3. Resource ID can be hidden (the object can be found anyway)
For example the original plural routes to the users profile (routes.rb):
resources :profiles, except: [:index, :destroy]
for the model:
class Profile < ActiveRecord::Base
  belongs_to :user
  validates :user, presence: true
end
give access to the RESTful controller (profiles_controller.rb):
class ProfilesController < ApplicationController
  def show
    @profile = Profile.find params[:id]
  end

  def new
    @profile = Profile.new user_id: user.id
  end

  def create
    @profile = Profile.new user_id: user.id
    @profile.attributes = params[:profile]
    render(action: :new) unless @profile.save
  end

  def edit
    @profile = Profile.find params[:id]
  end

  def update
    @profile = Profile.find params[:id]
    @profile.attributes = params[:profile]
    render(action: :edit) unless @profile.save
  end
private
  def user
    @user = User.find session[:user_id]
  end
end
in the view:
  <%= link_to 'Profile', profiles_path(@user.profile) %>
A user can have only one profile. It can created, updated, but not deleted. After the user accounted, the User object is always present. That is why the Profile ID is not required to be parameterized.

Refactoring starts with singularizing the routes (routes.rb):
resource :profile, except: :destroy
to the refactored controller (profiles_controller.rb):
class ProfilesController < ApplicationController
  def show
    @profile = user.profile
  end

  def new
    @profile = user.build_profile
  end

  def create
    @profile = user.build_profile
    @profile.attributes = params[:profile]
    render(action: :new) unless @profile.save
  end

  def edit
    @profile = user.profile
  end

  def update
    @profile = user.profile
    @profile.attributes = params[:profile]
    render(action: :edit) unless @profile.save
  end
private
  def user
    @user = User.find session[:user_id]
  end
end
and the refactored link in the view:
  <%= link_to 'Profile', profile_path %>
Please note the ProfilesController keeps being pluralized.
All its 6 standard routes are listed:
Path HTTP verb Action Behaviour
/profile POST create Creates a new profile
/profile/new GET new Returns the form a new profile
/profile GET show Displays the profile for the accounted user
/profile PUT update Updates the profile for the accounted user
/profile/edit GET edit Returns the form for editing profile for the accounted user
/profile DELETE destroy Deletes the profile for the accounted user (since the route is needless, it was removed from the standard routes)
Please compare the generated singular routes with their plural companions. Concluding singular resources simplify routing in dedicated cases.
Further articles of interest:

Supported by Ruby 2.1.1 and Ruby on Rails 3.2.17

Sonntag, 17. August 2014

Let it walk like a duck!

Please, do not let the title irritate you. It is just an controversial introduction to duck typing in Ruby, backed by the well-know saying:
"When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck."
Duck types are public interfaces that are not tied to any specific class. They are about the object's methods and properties, rather that its inheritance from a certain class. In a nutshell:
Behaviour over class membership
Following that pattern helps to improve:
  1. readability (less code for all message sender)
  2. add enormous flexibility
  3. reduces class coupling and therefore increases maintainability
The following original code contains 3 classes, each offering one getter method (Ingredient#name, Food#brand and Product#brand) returning a String.
class Drug
  attr_accessor :dope, :brand
end

class Food
  attr_accessor :ingredients
  def labeling
    ingredients.map { |ingredient| ingredient.name }.join(', ')
  end
end

class Clothing
  attr_accessor :name
end
and a Bill class for printing out:
class Bill
  def print_name product
    return puts "#{product.brand} (#{product.dope})" if product.respond_to? :dope
    return puts product.labeling if product.respond_to? :labeling
    puts product.name
  end
end
The Bill#print_name can be refactored by also duck typing the 3 classes:
class Drug
  attr_accessor :dope, :brand
  def name
    "#{product.brand} (#{product.dope})"
  end
end

class Food
  attr_accessor :ingredients
  def labeling
    ingredients.map { |ingredient| ingredient.name }.join(', ')
  end
  alias_method :name, :labeling
end

class Clothing
  attr_accessor :name
end
All 3 classes now respond to name and can called in Bill#print_name like:
class Bill
  def print_name product
    puts product.name
  end
end
Further articles of interest:

Supported by Ruby 2.1.1

Sonntag, 10. August 2014

Do not break the law of Demeter!

The definition of the law of Demeter also known as the principle of least knowledge is:
A given object should assume as little as possible about the structure or properties of anything else (including its subcomponents).
It also can be described by:
  1. Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.
  2. Each unit should only talk to its friends; don't talk to strangers.
  3. Only talk to your immediate friends.
Given the following example with 3 classes (ActiveRecord models):
class Category < ActiveRecord::Base
  attr_accessible :name
end

class Food < ActiveRecord::Base
  attr_accessible :name, :category_id
  belongs_to :category
end

class Recipe < ActiveRecord::Base
  attr_accessible :name, :food_id
  belongs_to :food
end
and accessing the recipes category name in the ERB template in that way:
Recipe: <%= @recipe.name %>
Recipe food category: <%= @recipe.food.category.name if @recipe.food and @recipe.food.category %>
is definitely a bad practice for various reasons:
  1. The Recipe object has not only to know about its associated Food object, but also about how the food object is associated to the Category object.
  2. The path gets longer the more objects are involved and the more the Recipe object has to know about other objects associations.
  3. An object during the path could be nil, and hence the path could be broken. Therefore a long security condition statement is needed every time the path is gone.
  4. Repeating the security condition everywhere the path was used, is hard to maintain, if even only one association changed.
Those points mean that the law of Demeter was broken.
It can be fixed by hiding the knowledge about the directly associated object in an instance method like:
class Category < ActiveRecord::Base
  attr_accessible :name
end

class Food < ActiveRecord::Base
  attr_accessible :name, :category_id
  belongs_to :category

  def category_name
    category.name  if category
  end
end

class Recipe < ActiveRecord::Base
  attr_accessible :name, :food_id
  belongs_to :food

  def food_category_name
    food.category_name if food
  end
end
The Recipe object only knows about its associated Food object and how to get its category_name, without knowing HOW the Food object gets the category_name. But the Food object just knows how to get the Category name. The knowledge was appropriately hidden and can accessed like:
Recipe: <%= @recipe.name %>
Recipe food category: <%= @recipe.food_category_name %>
Well, Ruby on Rails is handy enough to offer some syntactic sugar for delegating methods with the help of Module#delegate. That is why the models look better delegating the Category name:
class Category < ActiveRecord::Base
  attr_accessible :name
end

class Food < ActiveRecord::Base
  attr_accessible :name, :category_id
  belongs_to :category

  delegate :name, to: :category, prefix: true, allow_nil: true
end

class Recipe < ActiveRecord::Base
  attr_accessible :name, :food_id
  belongs_to :food

  delegate :category_name, to: :food, prefix: true, allow_nil: true
end
The detailed options can be read in the Module#delegate API documentation. The ERB template need not to be changed:
Recipe: <%= @recipe.name %>
Recipe food category: <%= @recipe.food_category_name %>

Supported by Ruby 2.1.1 and Ruby on Rails 3.2.17

Sonntag, 3. August 2014

Stringify your ActiveRecord model objects!

The view in a Ruby on Rails project very often is about string representations of the stored ActiveRecord model objects. For example:
class Food < ActiveRecord::Base
  validates :name, presence: true
  belongs_to :category
end

class Category < ActiveRecord::Base
  validates :name, presence: true
  attr_accessible: name
end
and in the view the objects (food and its category) are represented by their name attribute:
Food name: <%= @food.name %>
Food category: <%= @food.category.name unless @food.category.nil? %>
That works actually and the generated HTML could look like:
Food name: Apple Cider Cookie
Food category: Sweets
The ERB templating in Ruby on Rails sends the to_s message to the embedded result anyway. So something like that:
Food name: <%= @food %>
Food category: <%= @food.category %>
would not throw an exception, if the category was nil (since nil.to_s returns a blank string) and send the ActiveRecord::Base#to_s to the objects. Please note, not only the methods name are left out, but also the unless condition can be omitted, which looks much nicer in the view. At that point the result looks like:
Food name: #<Food:0x000000070c5010>
Food category: #<Category:0x0000000153b708>
It is the natural string representation of ActiveRecord model objects but does not serve any purpose. Overwriting ActiveRecord::Base#to_s in particular models is absolutely reasonable:
class Food < ActiveRecord::Base
  validates :name, presence: true
  belongs_to :category
  def to_s
    name
  end
end

class Category < ActiveRecord::Base
  validates :name, presence: true
  attr_accessible: name
  def to_s
    name
  end
end
and in the ERB template:
Food name: <%= @food %>
Food category: <%= @food.category %>
results in:
Food name: Apple Cider Cookie
Food category: Sweets
The big plus for overwriting ActiveRecord::Base#to_s is that the typical string representation for the model objects can be defined and especially in the case of more complex string representations it is absolutely reasonable.

Supported by Ruby 2.1.1 and Ruby on Rails 3.2.17

Sonntag, 27. Juli 2014

Merge your ActiveRecord scopes!

ActiveRecord scopes help to abstract out several SQL fragments in a elegant object oriented manner. Since they are combineable and reuseable, they help to maintain database related code.
The original ActiveRecord models:
class Food < ActiveRecord::Base
  has_and_belongs_to_many :ingredients
  scope :preservative, joins(:ingredients).where("ingredients.preservative" => true)
end

class Ingredient < ActiveRecord::Base
end
are tied together via a 1:n relationship. Furthermore there is scope, which shrinks the amount of foods having preservative ingredients. It has a name :preservative and receives a join and a condition (for more detailed explanation of ActiveRecord scopes go read: Scope the model!).
But it suffers knowing about the internal table structure of a different model, which increases the coupling between both classes.
That issue can be solved by merging scopes of different model classes:
class Food < ActiveRecord::Base
  has_and_belongs_to_many :ingredients
  scope :preservative, joins(:ingredients).merge(Ingredient.preservative)
end

class Ingredient < ActiveRecord::Base
  scope :preservative, where("#{table_name}.preservative" => true)
end
Now the Ingredient model takes the responsibility for its scope, where it belongs (please note that using ActiveRecord::ModelSchema::ClassMethods#table_name removes the knowledge about the table name in the scope itself).
The interesting part is the scope Food#preservative. Besides still joining the other model via the association, it uses ActiveRecord::SpawnMethods#merge for merging the scope Ingredient#preservative into the scope Food#preservative.
The usage:
preservative_foods = Food.preservative
Further articles of interest:

Supported by Ruby 2.1.1 and Ruby on Rails 3.2.17

Sonntag, 20. Juli 2014

Use a font for form check boxes! ... CSS based.

Native form check boxes suffer some disadvantages. They:
  1. are not cross browser consistent (Safari, Chrome, Opera or Firefox)
  2. are not scaleable
  3. are not fully styleable (and therefore may not fit to the look and feel of the page)
Native web form check boxes could look like:
The check boxes above are built on:
with some CSS:
div.checkboxes input[type=checkbox]{
  float: left;
  margin-right: 1em;
}
div.checkboxes label{
  display: block;
  margin: 0.5em;
}
Compare the native look and feel with the CSS font based only solution:
Since the check box font solution is based on CSS styles only, the HTML structure is still the same (except the input elements have the additional CSS class 'hidden'), but with some additional CSS:
@font-face {
  font-family: 'FontAwesome';
  src: url(/assets/fontawesome-webfont.eot?v=4.1.0);
  src: url(/assets/fontawesome-webfont.eot?#iefix&v=4.1.0) format("embedded-opentype"), 
    url(/assets/fontawesome-webfont.woff?v=4.1.0) format("woff"),   
    url(/assets/fontawesome-webfont.ttf?v=4.1.0) format("truetype"), 
    url(/assets/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular) format("svg");
  font-weight: normal;
  font-style: normal;
} 
.hidden{
  display: none;
}
div.checkboxes input[type=checkbox].hidden + label:before{
  font-family: FontAwesome;
  font-size: 1.5em;
  font-style: normal;  
  cursor: pointer;
}
div.checkboxes input[type=checkbox].hidden + label:before{
  content: "\f096";
  margin-right: 1em;
  position: relative;
  top: 0.2em;
}
div.checkboxes input[type=checkbox].hidden:checked + label:before{
  content: '\f046';
  color: #A00000;
}
div.checkboxes input[type=checkbox].hidden:hover + label:before{
  font-size: 2em;
}
div.checkboxes input[type=checkbox].hidden:active + label:before{
  text-shadow: 0px 0px 5px #666;
}
In the example the awesome font 'Awesome' was used.
It is important to include the font into the page with '@font-face'. That forces the clients to download the font once (after the font was downloaded the clients are considered to hold it in their cache).
Please note, that the check box inputs are hidden, but still existing.
Furthermore the font content is styled before the label by using the pseudo class ':before'. In combination with the state of the check box by using the CSS3 pseudo class ':checked' the content is overridden.
All following styles are just for improving the user experience, although this is pretty subjective and can vary depending on the use case.
The technique can be applied to other form controls as well, like radio buttons.

Firefox 21+, Chrome 21+, Safari 5.1+, Opera 12.1+, IE 9+, Android browser 2.3+, iOS Safari 6.0+, Opera min 5.0+

Sonntag, 13. Juli 2014

Differ between Proc and lambda in Ruby!

First of all there is no difference between a Proc (read Do the Proc! ... a Ruby closure) and a lambda (read Have a lambda! ... a Ruby closure) in Ruby, technically spoken. Both are Proc objects:
Proc.new {}
=> #<Proc:0x000000029642c0@(irb):1>
lambda {}
=> #<Proc:0x000000029642c0@(irb):2 (lambda)>
but with a different flavor (please note the second object stringification).
Well, but that's not the only difference (otherwise having 2 equal closure types in Ruby would not make any sense).
The differences are:
  1. lambda check the number of arguments and Procs do not.
  2. Proc and lambda treat return differently
A lambda checks the number of arguments:
lamda = lambda { |language| puts language }
lamda.call 'Ruby'          # prints Ruby
lamda.call                 # ArgumentError: wrong number of arguments (0 for 1)
lamda.call 'Ruby', 'Java'  # ArgumentError: wrong number of arguments (2 for 1)
unlike the Proc:
proc = Proc.new { |language| puts language }
proc.call 'Ruby'          # prints Ruby
proc.call                 # prints nothing
proc.call 'Ruby', 'Java'  # prints Ruby, but ignores Java
In terms of the second difference, a lambda returning something explicitly, will not force the environment (of the closure) to return either:
def lambda_environment
  lamda = lambda { return }
  lamda.call
  puts 'Ruby'
end
lambda_environment # prints Ruby
The lambda returns into its environment and let it end its processing.
But the Proc does not:
def proc_environment
  proc = Proc.new { return }
  proc.call
  puts 'Ruby'
end
proc_environment # does not print anything
The Proc forces its environment to return immediately. Further articles of interest:

Supported by Ruby 2.1.1