views:

20

answers:

1

I've got a one-to-many relationship from Treatment to Cost. The reason for this is because for invoicing and tax purposes we need to keep a record of changes in price for a treatment. So this is implemented by saying that the cost is equal to the most recent cost entry associated with that treatment.

This feature needs to be completely transparent to the user, they shouldn't know anything about the historical costs, just that there's a current one.

So when they hit edit, and do an update, if the cost of the treatment were to change, I then want to update the cost table also. The problem I have is with the models being represented in a form.

<% form_for([:admin, @treatment]) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </p>
  <p>
    <%= f.label :description %><br />
    <%= f.text_field :description %>
  </p>
  <p>
    <%= f.label :duration %><br />
    <%= f.text_field :duration %>
  </p>
  <p>
    <%= f.submit 'Save' %>
  </p>
<% end %>

So Treatment has_many :cost in the model, and in this form I want to have the cost field with the latest cost in it. For a start, how do I do that? Additionally, how do I update the cost model if the cost has changed? I'm assuming it's done in the controller, but if I have a text_field for the cost, how do I disassociate it with the @treatment model?

Cheers

A: 

I had a similar issue, so I had my has_many association but then I had a has_one association that pointed to the most recent version.

NOTE: I am using MSSQL, so your syntax might be a little different.

class Treatment < ActiveRecord::Base
  has_many :costs
  has_one :current_cost, :class_name => "Cost", 
                         :conditions => "costs.id = (SELECT MAX(c.id) 
                                                            FROM costs c
                                                            WHERE c.treatment_id = costs.treatment_id)"
end

I started with this:

class Treatment < ActiveRecord::Base
  has_many :costs

  def current_cost
    self.costs.last(:order => "id")
  end
end

But after it got large enough, I needed to minimize database dips and this was becoming a bottleneck.

If you had the ability of setting an enabled field in the costs model and using a validation to ensure that only one cost is enabled per treatment. Then I would recommend:

class Treatment < ActiveRecord::Base
  has_many :costs
  has_one :current_cost, :class_name => "Cost", :conditions => ["costs.enabled = ?", true]
end

I hope this helps!

Geoff Lanotte
Will have a bash at this either tonight or the weekend when I'm at home :)
Kezzer