Skip to content


JQuery Autocomplete updating a document element (not the dropdown)

I came across the requirement of updating a page element from the result of an Autocomplete. The server results were to be placed in a select element as set of option items.

I had to overwrite some JQuery UI Autocomplete private methods as apparently there was no easy way of generating HTML and embedding it in the right spot on the page:

The JSON server response:

[{"id":"aaa","id_and_ba_name":"bbb"}, ...]

   var auto = $("#lc").autocomplete({
      minLength: 3,
      delay: 600,
      dataType: 'json',
      source: '/remote/action',
      open: function() {
         $("ul.ui-autocomplete").remove(); //removes the ul styling for dropdown
      }
    })
    auto.data("autocomplete")._renderMenu= function(element, items) {
      //treats the DOM element as the menu where items are to be placed
      var self = this;
      $('#the_select_element').show().html('');
      $.each( items, function( index, item ) {
        self._renderItem($('#the_select_element'), item );
      });
    }
    auto.data("autocomplete")._renderItem= function(element, item) {
       // generate options elements and adds them to menu
       return $("<option></option>")
        .data("item.autocomplete",item)
        .attr("value",item.id)
        .append(item.id_and_ba_name)
        .appendTo(element);
    }

JQuery 1.8.16
Rails 3.1

Posted in Ruby, Web.

JRuby and Polyglot

JRuby 1.5.6 (I know. Old)
Rails 3.0.1
Polyglot 0.3.3

UPDATE: see easier fix below

Getting the following error when bundling:

Java::JavaLang::ArrayIndexOutOfBoundsException: An error occured while installing polyglot (0.3.3), and Bundler cannot continue.
Make sure that `gem install polyglot -v '0.3.3'` succeeds before bundling.

JRuby YAML parser is erring with this version of Polyglot (don’t you love JRuby!!).

‘gem dependency -R polyglot’ will get you the reverse dependencies on the library. In this case it’s ‘treetop’

Had to edit the ‘gemspec’ files and restrict the version of polyglot to ‘< 0.3.3'

Example - From
s.add_runtime_dependency(%q , [">= 0"])
To
s.add_runtime_dependency(%q , [">= 0", "< 0.3.3"])

Yak shaving!!!

UPDATE: EASIER FIX:
just use `gem ‘polyglot’, ’0.3.2′` in your Gemfile, it might just do the trick.

Posted in Ruby.

Rails, nested attributes and before_save callbacks

I had a Project model with a many ProjectWell (as in oil) association. Taking advantage of the accepts_nested_attributes, I was able to persist both Project and ProjectWell attributes through a single web form.


class Project < ActiveRecord::Base
  has_many :project_wells
  accepts_nested_attributes_for :project_wells
end

class ProjectWell < ActiveRecord::Base
  belongs_to :project
end

Now, the ProjectWell had fields that I wanted to calculate and assign on each ProjectWell save. Naturally a before_save operation (within an observer or such) would've been sufficient. The main requirement I had was to have all ProjectWell callbacks fired regardless of the Dirty state of the ProjectWell object.

Given Project p with an associated ProjectWell p_well (both already exist in the database):


p.update_attributes!({"project_well_attributes" => [{'id' => p_well.id, 'name' => p_well.name}]})

This will NOT update the ProjectWell (p_well) object in the database, and hence will NOT fire any of the required callbacks. The main reason is that the p_well attributes didn't change. The name attribute is the same as the one already in persisted.

My next attempt was to try to disable the partial_updates for ActiveRecord. In an initializer, I've placed this configuration:


ActiveRecord::Base.partial_updates = false

What this does was disable selective attribute updates for ProjectWells (and all other objects). In other words; it updates all ProjectWell attributes, regardless of whether or not those particular attributes have changed. But this happens ONLY when ActiveRecord detects at least ONE changed attributes.

In my case, there were no changes in any of the attributes, which made Rails skip the update operation altogether.

My work around was to 'simulate' an attribute change, in one of the attributes, even if it hasn't really changed by the user.

A first attempt was to create a virtual (non-persisted) attribute in the model (attr_accessor :force_save). Unfortunately, it changes to the attribute (corresponding to its default value) didn't trigger Rails dirty check.

A second attempt was by using '_will_change!' dynamic method. The method can force Rails into registering the corresponding attribute as a changed one.


  def force_save= val
    force_save_will_change!
    @force_save= val
  end

This threw an undefined method error of 'force_save_will_change!'.

The _will_change! method is only available for DB persisted attributes (defined in the corresponding table).

My next attempt made by selecting a non-virtual attribute to use the will_change! against.


  def name= val
    name_will_change!
    @name= val
  end

This resolved the issue by always setting the ProjectWell state to dirty update an update to name attribute, regardless if the previous name was the same as the new one.

Now, when executing the update_attributes - passing in the name attribute (whether with a name change or not) will fire off the save operation and consequently the before_save callback

Note: Setting 'autosave' and 'touch' on the relative association declaration didn't help.

Any other way of doing this?

Stack: Rails 3.1.0, JRuby 1.63, activerecord-oracle_enhanced-adapter 1.4, Windows XP

Posted in Ruby.

FactoryGirl with Oracle enhanced adapter – an attribute of name ‘id’ is not assigned

My question and answer are also posted on StackOverflow

I have an Oracle test table with ID column that is not a primary key, not an autoincrement and with no sequence defined. It only has NOT NULL defined. The corresponding structure in development schema is an Oracle View rather than a table with a primary key defined against the ID column.

My factory definition looks like:


FactoryGirl.define do
  factory :model do
    id 'abc'
  end
end

These tests fails


test "should build model 1" do
  w = FactoryGirl.build(:model)
  assert_not_nil w.id #fails - id is always nil
end

test "should build model 2" do
  w = FactoryGirl.build(:model, :id => 'abc')
  assert_not_nil w.id #fails - id is always nil
end

I've added attr_accessible :id to my model (just in case), but with no luck.

I've also defined id= method in my model def id= id; @id = id; end. The call is made to the method and @id is written, but looks like it is overwritten later in the callstack (between FactoryGirl and ActiveRecord).

Other attributes are normally assigned.

After a bit of digging - I found the I found the culprit:

The write method in ActiveRecord::AttributeMethods::Write module has the line:


attr_name = self.class.primary_key if attr_name == 'id'

It means that if the attribute name to be set has the name of 'id', pick the primary_key as the name of the attribute to assign the new value to. And since in my test table there is no primary_key returned by the oracle_enhanced_adapter (rightfully), the whole write operation is skipped.

My solution was to override the write method (only when running tests) skipping that line so that the id is written to.

Posted in Ruby.

Test Oracle Database Views with Rails

Testing Rails with a legacy oracle schema as a backend is always a challenge (fun?).

Rails relies no schema.rb to create its test database. The problem is that using the latest activerecord-oracle_enhanced-adapter (1.4.0), the application is unaware of the database views.

So, I’ve decided to create those DB views (development) as DB tables (test).


#names of views I'd like created
views = %W(VIEW1 VIEW2 VIEW2)
dev_schema = Rails.configuration.database_configuration["development"]["username"].upcase
test_schema = Rails.configuration.database_configuration["test"]["username"].upcase
views.each do |view|
  #for each of the views I need created
  # establish a connection first to development database
  ActiveRecord::Base.establish_connection(:development)
  # grant select on the view to the test user
  ActiveRecord::Base.connection.execute  "GRANT SELECT ON #{dev_schema}.#{view} TO #{test_schema}"
  # establish a connection to the test database
  ActiveRecord::Base.establish_connection(:test)
  # create the view as a table in the test database - 'where 1=0' discards importing data
  ActiveRecord::Base.connection.execute "CREATE TABLE #{test_schema}.#{view} AS SELECT * FROM #{dev_schema}.#{view} where 1=0"
end


The script can run as a db:test:prepare rake task or as being explicitly required somewhere at the beginning of the test_helper. And of course, this is just the initial working concept – it can be greatly improved.

JRuby 1.6.3
Rails 3.1
activerecord-oracle_enhanced-adapter 1.4.0

Posted in Ruby.

Die IE7. Die.

getElementById Method: Returns a reference to the first object with the specified value of the ID or NAME attribute.

Why the heck a method with called “getElementByID” return NAME matches?!

Here’s the story:

Two elements with different IDs, with one of the IDs matching the name of the other.


<textarea id="X" name="A">First</textarea>
<textarea id="A" name="whatever">Second</textarea>

document.getElementById('X').value
/* will return 'First' */

document.getElementById('A').value
/* will also return 'First' */

Posted in Web.

Rails – disable timezone conversions

In order to globally disable the use of TimeZone conversions for your (legacy?) application – here’s the proper configurations:

In config/application.rb (or config/environment.rb depending on Rails version):


    config.time_zone = 'Mountain Time (US & Canada)' #uncommented and set to proper zone
    config.active_record.default_timezone = :local
    config.active_record.time_zone_aware_attributes = false

Posted in Ruby.

Heroku timezone adjustment

Setting up timezone on Heroku instance using heroku gem (command line)

heroku config:add TZ=America/Edmonton
....
heroku console
>> Time.now
=> ... -0700 ...

Heroku apparently accepts zoneinfo timezones.

Posted in Ruby.

Contents Invalid public key / Fingerprint can’t be blank

Getting the above error message trying to deploy to Heroku (Windows, PuTTY keygen).

Turns out the public/private key files saved through putty aren’t of a valid OpenSSH format (expected by Heroku). You can still use Putty Keygen by copying the text generated under “Public key for pasting into OpenSSH authorized_key file” (save it to your *.pub)

I’m inching towards my first Mac. Windows is a frustration after the other.

UPDATE: working with Heroku/Git/SSH on a windows machine is a royal pain. One step closer to a MaxBook.

Follow these if you’re stuck:
- http://therubyway.wordpress.com/2008/12/11/using-heroku-and-windows/
- http://linux-sxs.org/networking/openssh.putty.html
- http://help.github.com/troubleshooting-ssh/
- http://code.google.com/p/msysgit/issues/detail?id=49

My setup so far is “Putty Keygen, Putty, Pageant, Git GUI”

http://code.google.com/p/msysgit/issues/detail?id=49

Posted in Ruby, Web.

NoMethodError: undefined method `eq’ for nil:NilClass

JRuby 1.5.2
Rails 3.0
activerecord-jdbc-adapter 0.9.7

This issue arises when setting table name with a schema name prefix. For those in the know – this is a must-have if you’re connecting to oracle using a non-owner username (activerecord-jdbc-adapter).


class Model < ActiveRecord::Base
  set_table_name '<schema>.<table>'
end

Now – tracking this down led to
lib/arel/engines/sql/relations/table.rb


def table_exists?
  @table_exists ||= @@tables.include?(name) || engine.connection.table_exists?(name)
end

The @@tables include table names as read from the connection (sans schema name). The comparison with the name always yields false resulting in an instantiation of an empty Header (with no attributes). Hence – alias_table[<attr>] always returned nil and nil.eq is undefined.

Anyways – as a work around (sorry: non tested monkey patch):

in your apps lib folder (provided that it’s auto-loaded) – create the arel_ext.rb


module Arel
  class Table
    def table_exists?
     #checking with only <table_name> rather than <schema_name>.<table_name>
      @table_exists ||= @@tables.include?(name.to_s.gsub(/.*\./, ''))|| engine.connection.table_exists?(name)
    end
  end
end

Reported on activerecord-jdbc-adapter list: http://kenai.com/jira/browse/ACTIVERECORD_JDBC-132

Posted in Java, Ruby.