Как обращаться с master-detail с помощью STI

Если роль является таблицей STI:

class Role< ActiveRecord::Base
   self.inheritance_column= :role_type 
end

И студент и советник наследуют роль:

class Student< Role
end

class Counselor< Role
end

А StudentDetail хранит дополнительную информацию об одном студенте:

class StudentDetail< ActiveRecord::Base
    belongs_to :student
end

Причем пользователь может быть как учеником, так и вожатым:

class User< ActiveRecord::Base
    has_many :roles
    has_one :student
    has_one :counselor
end

И номер — это столбец в StudentDetail, а role_id — это столбец в StudentDetail.

Можно ли заставить работать следующий синтаксис?

User.first.student.number

Значение: «если в таблице ролей есть один студент с user_id == User.first.id, тогда User.first.student не равен нулю, и если StudentDetail имеет role_id == Student.where («user_id =?», User.first.id) .first.id, сделайте так, чтобы «студент» действовал как запись StudentDetail и получил числовое поле».




Ответы (1)


У вас будет косвенное обращение User.first.student.student_detail.number из коробки. Я не думаю, что это очень больно :-)

Я вижу два варианта (как минимум), как идти дальше:

  • Определите методы для методов StudentDetail в Student:

    def number
      self.student_detail ? self.student_detail.number : nil
    end
    
  • Используйте отсутствующий метод, чтобы сделать это автоматически:

    def method_missing(name, *args, &block)
      self.student_detail ? self.student_detail.send(name, *args, &block) : nil
    end
    
person mliebelt    schedule 24.03.2012
comment
номер определения скважины; self.try(:student_detail).try(:number); конец был бы лаконичнее. В итоге я сделал has_one student_detail через student, но +1 для method_missing. - person nurettin; 31.03.2012