jGrowl in Rails for flash

Posted by kain Sat, 13 Sep 2008 17:58:00 GMT

Install JQuery and jGrowl plugin. Also include I18n.

  def display_flash
    flash_types = [:error, :warning, :notice]

    messages = ((flash_types & flash.keys).collect do |key|
      "$.jGrowl('#{flash[key]}', { header: '#{I18n.t(key, :default => key.to_s)}', theme: '#{key.to_s}'});"
    end.join("\n"))

    if messages.size > 0
      content_tag(:script, :type => "text/javascript") do
        "$(document).ready(function() { #{messages} });"
      end
    else
      ""
    end
  end

i18n url based breadcrumbs in Rails

Posted by kain Sat, 13 Sep 2008 17:50:00 GMT

in application_helper.rb

  # Generate URL-based Breadcrumbs.
  # Based on http://rubysnips.com/url-based-breadcrumbs
  # Modified and adapted for i18n by Claudio Poli (http://www.icoretech.org)
  def show_breadcrumbs(wrapper = "p", separator = " » ")
    r = []
    r << link_to(I18n.t(:home), "/")
    url = request.path.split('?')
    segments = url[0].split('/')
    segments.shift
    segments.each_with_index do |segment, i|
      title = segment.gsub(/-/, ' ').titleize
      title = I18n.t(title.downcase.to_sym, :default => title)
      r << link_to_unless_current(title, "/" + (0..(i)).collect{ |seg| segments[seg] }.join("/"))
    end
    content_tag(wrapper, "#{I18n.t(:path)}: " + r.join(separator), :class => "breadcrumbs")
  end

My attempt to beautify Ruby code in TextMate

Posted by kain Sat, 13 Sep 2008 12:26:00 GMT

This is based on Paul Lutus work, version 2.4

#!/usr/bin/env ruby

=begin
/***************************************************************************
 *   Copyright (C) 2008, Paul Lutus                                        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
=end

PVERSION = "Version 2.4, 08/25/2008"

# Modified to work as a TextMate command by Claudio Poli (http://www.icoretech.org)

$tabSize = 2
$tabStr = " "

# indent regexp tests

$indentExp = [
  /^module\b/,
  /^class\b/,
  /^if\b/,
  /(=\s*|^)until\b/,
  /(=\s*|^)for\b/,
  /^unless\b/,
  /(=\s*|^)while\b/,
  /(=\s*|^)begin\b/,
  /(^| )case\b/,
  /\bthen\b/,
  /^rescue\b/,
  /^def\b/,
  /\bdo\b/,
  /^else\b/,
  /^elsif\b/,
  /^ensure\b/,
  /\bwhen\b/,
  /\{[^\}]*$/,
  /\[[^\]]*$/
]

# outdent regexp tests

$outdentExp = [
  /^rescue\b/,
  /^ensure\b/,
  /^elsif\b/,
  /^end\b/,
  /^else\b/,
  /\bwhen\b/,
  /^[^\{]*\}/,
  /^[^\[]*\]/
]

def makeTab(tab)
  return (tab < 0) ? "" : $tabStr * $tabSize * tab
end

def addLine(line,tab)
  line.strip!
  line = makeTab(tab)+line if line.length > 0
  return line + "\n"
end

def beautifyRuby

  comment_block = false
  program_end = false
  multiLine_array = []
  multiLine_str = ""
  tab = 0
  source = STDIN.read
  dest = ""
  source.split("\n").each do |line|
    if(!program_end)
      # detect program end mark
      if(line =~ /^__END__$/)
        program_end = true
      else
        # combine continuing lines
        if(!(line =~ /^\s*#/) && line =~ /[^\\]\\\s*$/)
          multiLine_array.push line
          multiLine_str += line.sub(/^(.*)\\\s*$/,"\\1")
          next
        end

        # add final line
        if(multiLine_str.length > 0)
          multiLine_array.push line
          multiLine_str += line.sub(/^(.*)\\\s*$/,"\\1")
        end

        tline = ((multiLine_str.length > 0) ? multiLine_str:line).strip
        if(tline =~ /^=begin/)
          comment_block = true
        end
      end
    end
    if(comment_block || program_end)
      # add the line unchanged
      dest += line + "\n"
    else
      comment_line = (tline =~ /^#/)
      if(!comment_line)
        # throw out sequences that will
        # only sow confusion
        while tline.gsub!(/\{[^\{]*?\}/,"")
        end
        while tline.gsub!(/\[[^\[]*?\]/,"")
        end
        while tline.gsub!(/'.*?'/,"")
        end
        while tline.gsub!(/".*?"/,"")
        end
        while tline.gsub!(/\`.*?\`/,"")
        end
        while tline.gsub!(/\([^\(]*?\)/,"")
        end
        while tline.gsub!(/\/.*?\//,"")
        end
        while tline.gsub!(/%r(.).*?\1/,"")
        end
        # delete end-of-line comments
        tline.sub!(/#[^\"]+$/,"")
        # convert quotes
        tline.gsub!(/\\\"/,"'")
        $outdentExp.each do |re|
          if(tline =~ re)
            tab -= 1
            break
          end
        end
      end
      if (multiLine_array.length > 0)
        multiLine_array.each do |ml|
          dest += add_line(ml,tab)
        end
        multiLine_array.clear
        multiLine_str = ""
      else
        dest += addLine(line,tab)
      end
      if(!comment_line)
        $indentExp.each do |re|
          if(tline =~ re && !(tline =~ /\s+end\s*$/))
            tab += 1
            break
          end
        end
      end
    end
    if(tline =~ /^=end/)
      comment_block = false
    end
  end

  STDOUT.write(dest)
  # uncomment this to complain about mismatched blocks
  # if(tab != 0)
  #   STDERR.puts "#{path}: Indentation error: #{tab}"
  # end
end

beautifyRuby

Rails I18n SimpleBacked Italian translation files

Posted by kain Thu, 28 Aug 2008 12:31:00 GMT

I opened up a little github repository to store italian language files for Rails’ recently integrated I18n gem.

You can find the files at http://github.com/masterkain/rails-i18n-italian-language/tree/master 

finder bangs in Rails Edge

Posted by kain Tue, 26 Aug 2008 11:06:00 GMT

Finally it’s here

#before
@user = User.find_by_uuid(params[:uuid]) || raise(ActiveRecord::RecordNotFound)
# after
@user = User.find_by_uuid!(params[:uuid])

I’m happy again.

Discover your REXML version in your Ruby installation 1

Posted by kain Tue, 26 Aug 2008 05:17:00 GMT

ruby -vrrexml/rexml -e 'p REXML::VERSION,PLATFORM'

DoS vulnerability in REXML

Posted by kain Mon, 25 Aug 2008 21:24:00 GMT

http://www.ruby-lang.org/en/news/2008/08/23/dos-vulnerability-in-rexml/

Some Rails / Ruby tricks you should know 1

Posted by kain Mon, 25 Aug 2008 04:17:00 GMT

Grab column names for a model with magic fields and primary key stripped out

>> Dictionary.content_columns.collect { |col| col.name }
=> ["it", "en"]
# or
>> Dictionary.content_columns.map(&:name)
=> ["it", "en"]

Get an ActiveRecord Model attributes

>> Dictionary.first.attributes
=> {"it"=>"ciao", "id"=>1, "en"=>"hello"}

Discover which column yields the data you’re looking for

>> Dictionary.first.attributes.index("hello")
=> "en"

Take out some given keys from an Hash easily

# I think rails should need a method similar to content_columns and attributes_names but for extracting content_values
>> Dictionary.first.attributes.except("id")
=> {"it"=>"ciao", "en"=>"hello"}

Remove all whitespace on both ends of a string, change multiple spaces into one

" foo   bar    \n   \t   boo".squish # => "foo bar boo"

Manage repetitive find conditions via a Hash

# Basic
>> Model.find(:all, :conditions => ['first_name LIKE :name OR last_name LIKE :name', {:name => "aname"}])
# Extended example
# available_languages is a method which returns an Array.
>> word = "hello"
>> conditions = [ Dictionary.available_languages.collect { |language_column| language_column + ' = :word' }.join(" OR "), { :word => word } ]
>> Dictionary.find(:first, :conditions => conditions)

Not really a rails feature but you can append methods to the "end" block

    query_string_array.inject('') do |string_so_far, current_word|
      string_so_far + ' ' + lookup_word_and_build_translation_string(current_word)
    end.squish

Returns an array with the names of the subclasses of a class

# This works in production mode or development with config.cache_classes =  true or when classes are loaded
>> Account.send(:subclasses).map { |o| o.to_s } # this is protected in AR
# or
>> Object.subclasses_of(Account).map { |o| o.to_s }

Build up a sentence from an array taking advantage of the new I18n rails adapter, without last comma

# This will also use the "connector" word you defined in your language, default for en-US is "and".
>> %w(a b c).to_sentence(:skip_last_comma => true)
=> "a, b and c"
# Add in your language file:

  # Used in array.to_sentence.
  support:
    array:
      sentence_connector: "e"

There’s a ton of other stuff, just browse Active Support files to find much more useful and time-saving extensions. Now go refactor your code and make it even more prettier :)

Transaction rollback on callback returning false on Rails Edge

Posted by kain Sun, 24 Aug 2008 15:28:00 GMT

Previously this would have committed the transaction but not carried out save or destroy operation.

The entire callback chain of a save, save!, or destroy call runs within a transaction. That includes after_*hooks. If everything goes fine a COMMIT is executed once the chain has been completed.

If a before_* callback cancels the action a ROLLBACK is issued. You can also trigger a ROLLBACK raising an exception in any of the callbacks, including after_* hooks.

Note, however, that in that case the client needs to be aware of it because an ordinary save will raise such exception instead of quietly returning false.

link to changeset

Again on Rails Edge i18n with SimpleBackend

Posted by kain Fri, 22 Aug 2008 21:56:00 GMT

one hour ago a changeset changed how i18n in rails edge behaves, the main feature, apart some bug fixes, are that the language files can be in yaml.

it-IT:
  activerecord:
    errors:
      # The values :model, :attribute and :value are always available for interpolation
      # The value :count is available when applicable. Can be used for pluralization.
      messages:
        inclusion: "non è incluso nella lista"
        exclusion: "è riservato"
        invalid: "è invalido"
        confirmation: "non coincide con la conferma"
        accepted: "deve essere accettata"
        empty: "non può essere vuoto"
        blank: "non può essere vuoto"
        too_long: "è troppo lungo (il massimo è {{count}} lettere)"
        too_short: "è troppo corto (il minimo è {{count}} lettere)"
        wrong_length: "è della lunghezza sbagliata (deve essere di {{count}} lettere)"
        taken: "è già in uso"
        not_a_number: "non è un numero"
        greater_than: "deve essere superiore a {{count}}"
        greater_than_or_equal_to: "deve essere superiore o uguale a {{count}}"
        equal_to: "deve essere uguale a {{count}}"
        less_than: "deve essere meno di {{count}}"
        less_than_or_equal_to: "deve essere meno o uguale a {{count}}"
        odd: "deve essere dispari"
        even: "deve essere pari"
        # Append your own errors here or at the model/attributes scope.
        can_only_contain_letters_and_numbers: "può contenere solo lettere e numeri"
        can_t_be_blank_or_is_not_valid: "non può essere vuoto o non valido"

      models:
        # Overrides default messages

      attributes:
        # Overrides model and default messages.
class ApplicationController < ActionController::Base
  before_filter :set_locale
  private
  # Sets the locale for the current request.
  def set_locale
    # I18n.default_locale returns the current default locale. Defaults to 'en-US'
    locale = params[:locale] || session[:locale] || (this_user.site_language if is_logged_in?) || I18n.default_locale
    # TODO: insert a conditional check there to make sure be choose a valid supported locale.
    session[:locale] = locale

    # Sets the current locale pseudo-globally, i.e. in the Thread.current hash.
    I18n.locale = locale
    # Allow client libraries to pass a block that populates the translation
    # storage. Decoupled for backends like a db backend that persist their
    # translations, so the backend can decide whether/when to yield or not.
    I18n.populate do
      # Allows client libraries to pass arguments that specify a source for
      # translation data to be loaded by the backend. The backend defines
      # acceptable sources.
      # E.g. the provided SimpleBackend accepts a list of paths to translation
      # files which are either named *.rb and contain plain Ruby Hashes or are
      # named *.yml and contain YAML data.)
      I18n.load_translations "lib/locale/#{locale}.yml"
    end
  end

Older posts: 1 2