Hi forummates,
I’m relatively new to Ruby and Rails and have been creating a prototype
Rails app to mimic an existing desktop application. I’ve tried several
tutorials and worked my way through Agile Web D. with Rails.
But there’s a seemingly simple event in the prototype that’s stopped me
in my tracks. I can’t save a record, and can’t figure out why!
Here’s the situation:
I have borrowers, loans, and payments tables (a borrower has_many loans,
a loan has_many payments through loans). I can add a new borrower, which
I do by giving the user a form in which to fill in the SSN, FirstName,
LastName of the borrower. They press a Save link which successfully
mimics the Submit button (thanks to another post to this forum), after
which they are taken to another form in which they can edit the rest of
the borrower record.
But the loan and payment situations are more complex. In both cases my
system generates some of the attributes (field values) that will go in
the record, and gets the rest via a form the user fills out. For example
when adding a loan, the system knows the borrower_id and supplies it
automatically. Adding a loan works okay now too.
My big problem comes when attempting to add a payment record. One of the
required fields (validates_presence_of) is TransDate (transaction date).
Even if the user fills that in, they get an error message: TransDate is
missing, and indeed it now appears blank on the screen.
I was hoping that learning how to do testing in Rails would help me
resolve this problem, but it’s only worse! I’ve had problems with the
test_create results in all three controllers. However, I’ve resolved the
issues with the borrowers and loans controllers - they had to do with
initializing required fields in the tests to simulate the user filling
in those fields in the real app. But this doesn’t seem to work with the
TransDate field in the payments_controller_test. For kicks, I tried
assigning @payment.TransDate = Date.today in the payment controller and
indeed, that puts today’s date into the record and saves it
successfully. However that same technique fails in the test:
post :create, :payment => { :PmtPeriodNum => 5, :TransDate => Date.today
}
So my problem is:
- In the real app, when a user creates a new payments record including
entering a TransDate, they get the error message “Transdate is missing”
and the date they entered disappears. - In the payments_controller_test I can’t figure out how to read what’s
in @payments. That is, a breakpoint set in the payments_controller
itself gets a @payment record with a nil TransDate (even when I set it
to Date.today in the test), but a breakpoint set in the
payments_controller_test always gets @payment = nil. In the wording of
the tests, symbols are used instead of instance variables and of course
the value of :payment is “:payment”.
On the data side of things, I compared the definition of the TransDate
field in the payments Mysql table with other date fields. TransDate is
defined differently in that it is not allowed to be null. If I leave the
default value blank, Mysql converts it to 0000-00-00. If I change the
default value to a valid date like 0001-01-01, the test and the app run
fine, but the app displays the phony default date in the form, where I
DON’T want it. So I changed the definition of TransDate in the test
table but that alone made no difference in my result. I also tried
assigning Date.today to one of the date fields in the loans table and
that test works fine.
So is this a problem with Rails reading Mysql tables? Or I am just going
about the coding or setup all wrong? I’m new to Ruby/Rails although I’ve
been programming for over thirty years and learn new stuff all the time.
I’ve tried googling this and although lots of ruby/mysql/null dates
problems show up, I haven’t been able to find one like mine. In the
test.log, the create action renders the test TransDate correctly as a
date version of today. In an irb session inside a breakpoint, Ruby
correctly assigns the date as well. But the test always fails, as does
the actual app form.
I tried removing the model’s validates_presence_of :TransDate and
changing the Mysql field to allow nulls. Only if I do both of those will
the test and the app run. But that puts me back to coding data
requirements in procedural code rather than in the table or model. Not
very DRY at all!
Now, whoever read this far gets a prize (and my amazed appreciation).
I’ll be even more appreciative if you can help me solve my problem!
Gratefully,
Shauna