Best way to model rules in Rails?

I have a Contract class, along the lines of:

class Contract < ActiveRecord::Base
  validates_associated :signatures
  validates_presence_of :title
  # ...
end

One or more Conditions might apply to a Contract. Each Condition
imposes some kind of restriction or rule on the Contract it applies
to. There are about ten different Conditions that may apply. A
Contract is invalid if any of its Conditions are not met.

For example, a DurationCondition may specify that a Contract is only
valid within some window, while a CreditCheckCondition may specify
that a Contract is only valid if all of the signatories have passed a
credit check. There may be multiple conditions of a given kind on a
Contract. Conditions are permitted to contain other conditions (for
example, you may have an OrCondition which is true if at least one of
its subordinate Conditions is true).

The current tentative implementation uses STI, but I'm not sure this
is the right approach. There are also some issues with getting
accepts_nested_attributes_for to instantiate the correct derived
Condition type (DurationCondition, etc.) instead of always #new-ing up
Conditions.

Given that I'm constrained to a single Postgres datastore, what's the
best way to model my Conditions and store this data?

~ jf

So surely a Contract has many Conditions (and that relationship is
polymorphic: DurationCondition, CreditCheckCondition, etc)? And you
can validate_associated conditions. That way each condition checks
itself for validity. The contract shouldn't have anything to do with
its conditions' validity - just pass the responsibility down to them.

So surely a Contract has many Conditions (and that relationship is
polymorphic: DurationCondition, CreditCheckCondition, etc)?

Correct.

And you
can validate_associated conditions. That way each condition checks
itself for validity. The contract shouldn't have anything to do with
its conditions' validity - just pass the responsibility down to them.

Sure, but what about actually modeling the Conditions themselves? Use
STI? Have a #serialize and keep their columns dynamic? etc. They each
store very distinct kinds of information.

~ jf

If the data is that different then have each sub-typed model have a
child-model for its specific information.
For example, I do this for one model this way:

class Attaching < ActiveRecord::Base
  belongs_to :file_attachment, :dependent => :destroy
  validates_associated :file_attachment
end

class AttachingTypeStock < Attaching
  belongs_to :stock, :foreign_key => :attached_to_id
  def attached_from
    self.stock
  end
end

class AttachingTypePerson < Attaching
  belongs_to :person, :foreign_key => :attached_to_id
  def attached_from
    self.person
  end
end

class Person < ActiveRecord::Base
  has_many :attaching_type_people, :foreign_key => :attached_to_id
  has_many :file_attachments, :through => :attaching_type_people
end

I could just as easily say that Model has_many Attachings, and that
wouldn't matter whether those Attachings were of type Person, or
Stock. Each type has its own validation, but shares a common
interface, so I can call attaching.attached_from to navigate back up
the relationships.

HTH