views:

348

answers:

3

I am looking at using Ruby on Rails for a storefront that has to make use of existing data, but I can create my own database schema if I need to. A lot of the fields in the existing data are char(1) emulating a boolean field (i.e. Y/N) for, I believe, cross-platform portability. Since the data is prone to change, I don't want to have to change the existing structure and convert these fields to bit/boolean fields.

If I do use Rails I really would like to make use of Ruby's beautiful boolean syntax and say something like <%= image_tag 'recycled.jpg' if product.recycled? %>, but will Rails recognize char(1) as a boolean, or do I have to define those methods myself in the model like:

class Product < ActiveRecord::Base
  # ... other stuff here
  def recycled?
    self.recycled == 'Y'
  end
end

I'm thinking I will have to redefine them myself, which is no big deal, I just want to make sure since using char(1) as yes/no values isn't something I've used in the past.

A: 

Can't you just wrap it in your database engine with a view or stored procedure to produce a consistent interface to your application?

Cade Roux
Thats really not ActiveRecord is used in Rails.
Jeremy
+1  A: 

I'd probably attack it at the model level - when you load a row into a model instance, compute a boolean attribute based on the char. Add a getter for the virtual attribute that returns this value, and a setter that updates both the boolean and the underlying char.

bradheintz
+1  A: 

As far as I know, what you describe is not possible with ActiveRecord out-of-the-box.

However, if you have a lot of columns like this you could look at doing a little bit of meta-programming to provide a declarative way to add the relevant accessor logic. Something like :-

class Product < ActiveRecord::Base

  yes_no_accessor :recycled

end

Another possibility is to monkey-patch ActiveRecord. I think the relevant method is ActiveRecord::ConnectionAdapters::Column.value_to_boolean(value). You could try overriding the ActiveRecord::ConnectionAdapters::Column::TRUE_VALUES constant to include 'Y'. I haven't actually tried this!

floehopper
I wonder if my way could work provided I have database-level constraints to make sure it's always either Y/N; I dont mind having to add "custom" recycled? methods that check the value; the migration (if I use them) would have it as a string with a limit of 1, just I want the nice way to access it
Wayne M
Your way will definitely work, but you will have to define custom accessors each time. My suggestions were all about making things easier if you have a lot of these columns, but perhaps this is unnecessary.
floehopper