Rails 2.1.0 – named_scope

New version of rails comes with a great feature called named_scope.

# in your model.rb

class Model < ActiveRecord::Base
 has_many ...
 belongs_to ...

 named_scope :active, :conditions => {:state => 'active'}
 named_scope :today, :conditions => ['date_created between ? and ?', Time.today.to_i, Time.today.to_i+3600*24-1]
 named_scope :by_date_asc, :order => 'date_created asc'
 named_scope :by_date_desc, :order => 'date_created desc'
 named_scope :user_name, lambda {|name| {:conditions => {:username => name}}

and you can use its as:

# somewhere in your code

  @data = Model.today
  @data = Model.today.active.by_date_asc
  @data = Model.user_name('some user').active.today.by_date_desc

own application configuration

./config/my_configuration.yml
MyConfig:
  username: my_username
  password: my_password
  host: my_host

be sure to enter spaces, NOT tabs

./config/environment.rb
require 'ostruct'
require 'yaml'

OwnConfigFile = "#{RAILS_ROOT}/config/my_configuration.yml"
if File.exist?(MyConfigFile)
  ::ApplicationConfig = OpenStruct.new(YAML.load_file(MyConfigFile))
end

in application:

config = ApplicationConfig.MyConfig;
puts config['username']

Exception handling

./lib/mymodule.rb

module MyModule

  class Error < RuntimeError; end
  class ConnectionError < Error; end

  def connect

    if something_failed?
      raise ConnectionError, "connection failed due to..."
    end
  end
end

somewhere in controller

include MyModule

  def do_connect
    begin
      connect
    rescue MyModule::ConnectionError => err
      flash.now[:notice] => err
    end
  end

Damn IE JS event behaviour

I’ve written some application in Rails, using prototype/scriptaculous javascript library. It works great in FF, but in IE it has some fails…

I’ve had following code:


<%= check_box "adsl_cpe_chk", "yes", {:onChange => "if (this.checked) { Element.show('adsl_cpe');} else { Element.hide('adsl_cpe');}"} %>
  
  

and if I clicked (set) checkbox, the select field was still hidden – until I clicked somewhere else – with IE only. I’ve discovered, if I replace onChange with onClick, it works ok. A few hours of trying everything are gone :(

Using GOOGLE API (WSDL example)

def search
  require 'soap/wsdlDriver'
  @title = 'Search Results'
  key = 'YOUR GOOGLE API KEY HERE'
  yoursite = 'YOUR SITE ADDRESS HERE'
  driver = SOAP::WSDLDriverFactory.new("http://api.google.com/GoogleSearch.wsdl").createDriver
  @results = driver.doGoogleSearch(key, @params['term']+" site:#{yoursite}", 0, 10, true, " ", false, " ", " ", " ")
end

and parsing data

<% for result in @results.resultElements %>
 <%= result.title %>
 <%= result.snippet %>
 <%= result.URL %>
<% end %>

Progress bar

from palm-dev e-mail list, credit goes to Logan Shaw

typedef struct
{
    RectangleType bounds;
    WinHandle savedbits;
} ProgBar;

void OpenProgressBar (ProgBar *progbar)
{
    UInt16 savebitserror;

    progbar->savedbits = WinSaveBits (& progbar->bounds, & savebitserror);
    WinEraseRectangle (& progbar->bounds, 0);
}

void CloseProgressBar (ProgBar *progbar)
{
    if (progbar->savedbits)
    {
        WinRestoreBits (
          progbar->bounds.topLeft.x, progbar->bounds.topLeft.y,
          progbar->savedbits);
    }
    else
    {
  /* maybe should enqueue a frmUpdateEvent instead, maybe not */
        WinEraseRectangle (& progbar->bounds, 0);
    }
}

void UpdateProgressBar (ProgBar *progbar, Int32 numerator, Int32 denominator)
{
    RectangleType fillrect;

    RctCopyRectangle (& progbar->bounds, & fillrect);
    fillrect.extent.x = progbar->bounds.extent.x * numerator / denominator;

    WinDrawRectangle (& fillrect, 0);
}

void TestProgressBar ()
{
    Int32 i;
    const Int32 max = 25;
    ProgBar progbar;

    progbar.bounds.topLeft.x = 20;
    progbar.bounds.topLeft.y = 70;
    progbar.extent.x = 120;
    progbar.extent.y = 20;

    OpenProgressBar (& progbar);
    for (i = 0; i <= max; i++)
    {
        UpdateProgressBar (& progbar, i, max);
        SysTaskDelay (SysTicksPerSecond() / 5);
    }
    CloseProgressBar (& progbar);
}

Using libraries

Load and initializing the library

#include
int MathLibRef = -1;
...
// is library already loaded?
err = SysLibFind("MathLib", &MathLibRef);
if (err != 0) {
  // negative, load
  err = SysLibLoad('libr', 'MthL', &MathLibRef);
  if (err == 0) {
    err = MathLibOpen (MathLibRef, 1);
  }
}

Closing library

if (MathLibRef != -1) {
  Err err;
  UInt16 usecount;
  err = MathLibClose (MathLibRef, &usecount);
  if (usecount == 0) {
    SysLibRemove (MathLibRef);
  }
}

Preferences

Preferences structure definition

typedef struct {
  int skeletonData;
} Prefs;
Prefs prefs;

Open preferences

void startApp() {
  Int16 prefSize = sizeof(Prefs);
  if ((PrefGetAppPreferences (AppCreator,
           1000, // pref database id
           &prefs,
           &prefSize,
            true) // saved during Hotsync
    == noPreferenceFound)
    || (prefSize != sizeof(Prefs))) {
          // default initialization, since discovered
          // Prefs was missing or old.
    prefs.skeletonData=1;
  }
}

Write preferences

void stopApp() {
  PrefSetAppPreferences (AppCreator,
        1000,  // pref database id
        1,   // version of pref database
        &prefs,
        sizeof(Prefs),
        true);  // saved during hotsync
}

Simple PHP security patch

I’ve created (after some weird experiences with users in my hosting) small php patch (for version 4.3.10), which disables remote includes.This patch doesn’t work with Zend Optimizer enabled unfortunately :(

Download the patch there. After applying, see php.ini-dist and readme.security

example of bad code:

<?php 
  $page = $_GET['page']; 
  include ($page); 
?>

example of better code:

<?php 
  // filter all unneeded characters 
  $page = eregi_replace("[^a-z0-9_]","", $_GET['page']).".inc.php"; 
  // test if $page exists and is file 
  if (strlen($page) && @file_exists($page) && @is_file($page)) { 
    require_once ($page); 
  } 
?>