Вопрос

I am fairly new to Rails and I would really appreciate some pointers in the right direction. I understand the pros and cons of STI.

What would be the best practices for modeling AR-relations with a combination of Single table inheritance and polymorphic associations in Rails 3.2? By deciding to use both would there be any important downsides of this appproach? Would Rails 4 change things?

I have the following models so far:

    class Course
      has_many :participants, class_name: 'User'
      has_many :events, as: :eventable
    end

    class User
      has_many :events, as: :eventable
      has_many :courses
    end

    class Resource
      has_many :events, as: :eventable
    end

    class Subject < Resource
    end

    class Location < Resource
    end

    class Medium < Resource
    end

    class Event
      belongs_to :eventable, polymorphic: true
    end

Looks relatively easy so far, but I am struggling with the complex associations. How would I setup the following associations with STI?

  • a course can have many resources (as subjects/locations)
  • a user can have many resources (as subjects/locations)
  • a resource can have many users (as contacts)
  • an event itself can have additional users (as teachers)
  • an event itself can have additional resources (as locations/subjects/medias)

Examples for what I would like to retrieve from the database

  • all events for a user
  • all events for a course
  • all combined events (user and course) for a participant
  • all associated resources of type location from an event
  • all associated teachers from an event
  • all resources of type location from a course
  • all resources of type subject from a user

TIA and best regards

Chris

Это было полезно?

Решение

You would use those, and some more of Rails' magic :)

class Course
  has_many :participants, class_name: 'User'
  has_many :subjects, conditions: ['type = ?', 'Subject']
  has_many :locations, conditions: ['type = ?', 'Location']
  has_many :events, as: :eventable
end

class User
  has_many :subjects, conditions: ['type = ?', 'Subject']
  has_many :locations, conditions: ['type = ?', 'Location']
  has_many :events, as: :eventable

  belongs_to :event, foreign_key: :teacher_id
end

class Resource
  has_many :contacts, class_name: 'User'
  has_many :events, as: :eventable
end

class Event
  belongs_to :eventable, polymorphic: true
  has_many :teachers, class_name: 'User'

  has_many :subjects, conditions: ['type = ?', 'Subject']
  has_many :locations, conditions: ['type = ?', 'Location']
  has_many :media, conditions: ['type = ?', 'Medium']
end

I think this covers all of your use cases.

note: You should probably rename your model from Media to Medium since Rails works better with singularized model names and you might run into some issues if you don't.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top