views:

115

answers:

3

MySQL allows the value of "0000-00-00" for date fields, however ActiveRecords treats an assignment to a Date value with that string as being nil.

I have a legacy application that relies on that exact field content for the notion of "Never", so if the customer last payment date is "0000-00-00" it acknowledges as being "Never" paid.

Is there a way I can override ActiveRecord (correct) validation for this date field and write this value to the database without getting my hands (too) dirty?

Thanks for any insight.

+1  A: 

I hate answering my own questions, but after a little more research about AR code itself, I came up with this solution:

class CustomerInfo < BillingDatabase
  belongs_to :customer

  alias_method :old_read_attribute, :read_attribute

  def read_attribute(attr_name)
    if attr_name == "lastpaid" and old_read_attribute(attr_name).blank?
      "0000-00-00"
    else
      old_read_attribute(attr_name)
    end
  end
end

I will leave this question open in case someone has a better approach or want to comment on possible flaws.

kolrie
If you hate answering your own questions - then don't. Especially **within 1 minute** after posting your question. Blatant attempts at rep gain are frowned upon on SO; they're ignored at best and backfire at worst.
ChssPly76
Oh really? Let me tell you ChssPly76 that I don't give a sh**. I am not here hunting for reputation. This was a legitimate question that was addressed first in RoR IRC Channel in freenode.net and then submitted here. I bet someone like you never had an insight after writing down a question, did you? I will make this a wiki thing, so I don't get repo points, just so you know how much of a repo chaser I am, looser.
kolrie
+1  A: 

You may find this slightly easier and it should achieve the same result without executing the method for every attribute in the model

class CustomerInfo < BillingDatabase
  belongs_to :customer

  def lastpaid
    value = read_attribute(:lastpaid)
    value.blank? ? "0000-00-00" : value
  end
end

You could of course refactor the code to call read_attribute twice and do the lastpaid method as a one-liner. It's a matter of style/minute performance differences really.

def lastpaid
  read_attribute(:lastpaid).blank? "0000-00-00" : read_attribute(:lastpaid)
end
Steve Weet
A: 

You could change the default value on the database to be "0000-00-00" using a proper sql alter table alter column ...; statement.

Omar Qureshi