How to upcase multibyte data in Rails

In one of my projects I needed that all data sent to a model were converted in upper case prior they validated and then saved, once valid. I've chosen to keep them in upper case for better readability. There was no problem with converting ASCII data. Everything worked like a charm. Problem started when I tried to save data in Cyrillic. upcase! just refused to modify non-ASCII characters.

Here's how I made it to work, finally.

class Address < ActiveRecord::Base
  before_validation :uppercase_data

  def uppercase_data
    %w{street city state country}.each do |x|
      self.send("#{x}=", self.send(x).mb_chars.upcase.to_s)
    end
  end
end

Maybe someone will suggest a more elegant solution?

Comfort Stick website launched today

Another project went public. A e-commerce web site for Comfort Stick skin care line of products. http://comfortstick.com/

Comfort Stick web site, public interface

Comfort Stick web site, admin area

Enumerable.each vs 'for' loops in Ruby

A few days ago I checked the code using the Ruby project roodi, and I received a warning saying "Don't use 'for' loops. Use Enumerable.each instead." I personally do not see any difference between these two versions of cycles, and attributed the problem of choice to issues of personal faith. I asked people in the !ruby group of identi.ca, but the answers were not convincing. Google also did not shed light on this question.

I changed the code to use Enumerable.each, just in case, and put the problem aside. But today, I found a sample code, that clearly demonstrates the difference:

loop1 = []
loop2 = []

calls = ["one", "two", "three"]

calls.each do |c|
  loop1 << Proc.new { puts c }
end

for c in calls
  loop2 << Proc.new { puts c }
end

loop1[1].call #=> "two"
loop2[1].call #=> "three"

One link method fits all

Today I've created a universal rails helper to deal with multiple models of a multi-language project in a common way:

def link_to_add(object, args={})
  return '' unless logged_in?
  object = [object] unless object.is_a?(Array)
  link = link_to(t("#{object.last.to_s}.add"),
                 new_polymorphic_path(object, args))
  content_tag :p, link
end

def link_to_edit(object, args={})
  return '' unless logged_in?
  object = [object] unless object.is_a?(Array)
  return '' if object.last.new_record?
  node = object.last.class.to_s.underscore
  link = link_to(t("#{node}.edit"),
                 edit_polymorphic_path(object, args))
  content_tag :p, link
end

def link_to_delete(object)
  return '' unless logged_in?
  object = [object] unless object.is_a?(Array)
  return '' if object.last.new_record?
  node = object.last.class.to_s.underscore
  link = link_to(t("#{node}.delete"), object,
                 :method => :delete,
                 :confirm => t("#{node}.confirm_deletion"))
  content_tag :p, link
end

Now all links to create, edit or delete an instance look nice and intuitive.

I type short

<%= link_to_add :post %>

instead of long

<% if logged_in? %>
<p><%= link_to t('post.add'), new_post_path %></p>
<% end %>

It handles nested routes. Just type

<%= link_to_edit [@post, @comment] %>

instead of

<% if logged_in? %>
<p><%= link_to t('comment.edit'),
               edit_post_comment_path(@post, @comment) %></p>
<% end %>

And my favorite one:

<%= link_to_delete [@post, @comment] %>

instead of

<% if logged_in? %>
<p><%= link_to t('comment.delete'), [@post, @comment],
               :method => :delete,
               :confirm => t('comment.confirm_deletion') %></p>
<% end unless @comment.new_record? %>

How to make ssh-copy-id without a headache

If you, like I today, cannot perform a passwordless login via ssh to a remote linux server after copying a public key to the server with ssh-copy-id command, please check if the key is actually presents among other authorized keys on the server. I found that sometimes it is not.

$ cat .ssh/authorized_keys
The agent has no identities.

To fix the problem just add the -i argument like below:

$ ssh-copy-id -i user@server.tld

Read other articles | Subsribe to RSS updates

Paul Philippov

Paul Philippov
Toronto, Ontario, Canada
39 years old, married
Linux, Ruby, Photography

Ohloh profile for Paul Philippov