Thursday, April 09, 2009

Character encoding in custom to_xml methods

I was writing some tests for my custom to_xml method on an ActiveRecord model and needed to check that the text had been escaped properly. to_xml changse lots of characters to XML entities and I couldn't find where that encoding happens. So I tossed a few exceptions into the xml serializer and found that the xml serializer calls to_xs on strings before including them in the xml. It's defined in:

activesupport-2.3.2/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb

So if you need to pattern match the output of your xml generator, you can call to_xs to get the text that it is going to output.

Saturday, December 13, 2008

Fixtures and foreign key contraints

I'm working on a project where the stakeholder wants foreign key constraints in the database. I've been reading all over about fixtures and foreign keys. It all the opinions I'm surprised I havn't read "Fixtures are stupid, don't use them". I've decided to rip out the fixtures and replace them with factories.

Tuesday, November 04, 2008

Minimum height on divs

This blog had a solution to minimum height for divs that worked so well for me that I just had to give it some link love:

http://www.greywyvern.com/code/min-height-hack

Wednesday, September 17, 2008

Back from the dead

So I received an email from someone today about my ext-extensions and he told me that he is also polyphasic and also has interests in property management (albeit from a different angle). That made me really happy and made me realize that my blog is a powerful way to build relationships with other people and that people actually read it. So I'm going to work on posting from time to time. Feel free to send me an email asking about anything, I love to connect with people.

Thursday, June 12, 2008

Getting Oracle to work with Rails 2

I'm working on a rails application that needs to connect to an Oracle database and we are using Rails 2.1. I tried to install ruby-oci8 and it was giving me errors, so here is the low down on getting it to work.

1) First you need to have the oracle client on your machine. I wanted to test things off site so I installed the 10g Express Edition (which is free) on my Ubuntu box and it worked great and included the client too. That meant that I didn't have to install the InstantClient or the other client, so I don't know how to do that yet. This wiki page gave me everything I needed to install the 10g xe on ubuntu.

2) You need to install the ruby-oci8 oracle driver bindings. On windows there is a binary, but on UNIX/Linux you have to compile it from source. Some people had troubles, but again, the 10g XE put all the headers and other files right where I needed them. Here is a great run down of how to compile the driver on Ubuntu with all its potential pitfalls.

3) Then you need the activerecord oracle adapter which doesn't come with Rails 2 by default. The Ruby on Rails wiki said to download this file and put it at "/lib/active_record/connection_adapters" in your active_record gem or rails installation.

4) Finally you need to create a user on the Oracle server and put the database "name" in your database.yml file. Here is the string I used for the 10g XE server: "database: 127.0.0.1:1521/XE". The service part after the host and port needs to come from the tnsnames.ora file on the client machine. You don't need a "host:" entry. This is because the host is in the database line and the username defines your tablespace so you don't have a database name like you do in mysql.

After all that try and run your migrations and it should work.

Friday, May 30, 2008

Another point of defensive programming

Another point of defensive programming that I need to work on is not drilling too deep into an object. "object.relation.group_of_attributes.value" is bad code. Any time something changes inside, you have to change code in multiple other locations.

I've often used the excuse, "But requiring accessors reduces my flexibility." But now I realize that that kind of flexibility leads to very fragile code, makes testing impossible because you have hundreds of possible failure modes and prevents you from installing any central code to deal with those failure modes.

Shame on me.

Don't assume your data is valid

I've come to think that you should never code with the assumption that your data is valid. Now that doesn't mean that you're going to get the desired result if your data is invalid, maybe you just don't have what you need. But your code should try and do as much as it can with as little as possible.

For example, if you have a rails controller that returns a collection, don't let an exception accessing one of those objects prevent the entire list from returning. If you have a shopping cart and heaven forbid, you code finds an object that doesn't pass validations but is nonetheless persisted in the database, don't return an error page, log the issue and return a partial list and telling the user that an error occurred and some items had to be removed from their basket.

This has applications in large scale applications too, where maybe you don't have a strict database schema or you can't run migrations on your entire dataset everytime you make a code change. Your code is going to receive data that is out of date, incomplete, incorrectly formatted, or just plain broken. Take any data your code receives, don't make any assumptions and do the best you can. Your program will be more flexible, more resilient, and it will be more likely when an major error occurs that the user will be able to continue in some way.