views:

53

answers:

1
I have some STI structure like following:

class Assignment < ActiveRecord::Base 
  has_many :criteria, :class_name => "Criterion", :order => :position
end

class Criterion < ActiveRecord::Base
  # Represents a criterion used to mark an assignment that
  # being the super class for all different criterias
  set_table_name "criteria" # set table name correctly
  belongs_to  :assignment
  validates_associated :assignment, :message => 'association is not strong with an assignment'
  validates_presence_of :assignment_id
  validates_numericality_of :assignment_id, :only_integer => true, :greater_than => 0, :message => "can only be whole number greater than 0"
  validates_uniqueness_of :criterion_name, :scope => :assignment_id, :message => 'is already taken'
  validates_presence_of :criterion_name,:assignment_id
end

class FlexibleCriterion < Criterion
  has_one :flexible_criterion_attribute, :class_name => "FlexibleCriterionAttribute"
  accepts_nested_attributes_for :flexible_criterion_attribute
  default_scope :include => :flexible_criterion_attribute
end

class FlexibleCriterionAttribute < ActiveRecord::Base
  belongs_to  :criterion, :class_name => "FlexibleCriterion"
  validates_presence_of :max
  validates_numericality_of :max, :message => "must be a number greater than 0.0", :greater_than => 0.0

  DEFAULT_MAX = 1

end

Alright, I have uploaded my current working codes. So basically the problem is: When I use a method like criterion = assignment.criteria.find_or_create_by_criterion_name("AAA"), I will get an object of criterion. But I want cast this object to flexiblecriterion so that I can assign the value of criterion.flexible_criterion_attribute

Thx in advance!
+1  A: 
  1. If assignment.criteria.find_or_create_by_criterion_name("AAA") returns a record in which type column has value FlexibleCriterion, it will automatically cast the object to FlexibleCriterion.
  2. If you want to ensure that only FlexibleCriterion is returned, modify your finder like this: assignment.criteria.find_or_create_by_criterion_name_and_type("AAA", 'FlexibleCriterion')
Swanand
Hi, Swanand, thx for the answer.However, the 2nd point won't actually work, it will still return a :#<Criterion id: 4, type: "FlexibleCriterion", criterion_name: "XXXTTT", assignment_id: 1, weight: nil, position: nil, description: nil, created_at: "2010-03-25 03:22:35", updated_at: "2010-03-25 03:22:35">But you are right, at 1st. After it is created, it will always return a FlexibleCriterion.
Brian