【问题标题】:Rails Associations Riddle: User, Lecturer, Student and EventRails 关联之谜:用户、讲师、学生和活动
【发布时间】:2013-05-12 15:11:21
【问题描述】:

我已经在 Google 上搜索过、阅读过文档并观看过 railscast,但我无法理解这一点。 请帮忙。我在 Ubuntu 13.04 上运行最新的稳定 Rails 和 Ruby 1.9.3。

我有一个User 模型和一个Event 模型。 目前,两者之间存在has_and_belongs_to_many 关系。

然而,在现实生活中,UserEvent 相关,既可以是Lecturer,也可以是StudentUser 可以同时是 StudentLecturer,但不能用于同一个事件。 LecturerStudent 在我的应用程序中还不是模型,我不确定它们是否应该是单独的模型。 我需要帮助来实现这个逻辑。

我想要实现的是这样的:

Event.first.lecturers # 应该返回作为此特定事件讲师的用户。

Event.first.students # 应该返回该特定事件的学生用户

User.first.events :as => :student # 应该返回特定用户的事件,其中 用户是学生

User.first.events :as => :lecturer # 应该返回特定用户的事件,其中 用户是讲师

我在想has_many :through 关联可能会起作用,但我很困惑。 任何和所有的指导表示赞赏。

问候,

纳迪姆

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 activerecord ruby-on-rails-4 rails-models


    【解决方案1】:

    您可以创建两个连接表 events_studentsevents_lecturers 并像这样设置模型

    class Event < ActiveRecord::Base
      has_and_belongs_to_many :students, :class_name => 'User', :join_table => :events_students, :association_foreign_key => :user_id
      has_and_belongs_to_many :lecturers, :class_name => 'User', :join_table => :events_lecturers, :association_foreign_key => :user_id
    end
    
    class User < ActiveRecord::Base
      has_and_belongs_to_many :student_events, :class_name => 'Event', :join_table => :events_students, :association_foreign_key => :event_id
      has_and_belongs_to_many :lecturer_events, :class_name => 'Event', :join_table => :events_lecturers, :association_foreign_key => :event_id
    end
    

    然后访问它:

    Event.first.students
    Event.first.teachers
    User.first.student_events
    User.first.lecturer_events
    

    更新。

    另一种解决方案是使用 has_many :through

    class User < ActiveRecord::Base 
      has_many :event_assignments
      has_many :student_events, :through => :event_assignments, :source => :event, :conditions => {'event_assignments.type' => 'EventAssignment::Student'}
      has_many :lecturer_events, :through => :event_assignments, :source => :event, :conditions => {'event_assignments.type' => 'EventAssignment::Lecturer'}
    end
    
    class Event < ActiveRecord::Base 
      has_many :event_assignments
      has_many :students, :through => :event_assignments, :source => :user, :conditions => {'event_assignments.type' => 'EventAssignment::Student'}
      has_many :lecturers, :through => :event_assignments, :source => :user, :conditions => {'event_assignments.type' => 'EventAssignment::Lecturer'}
    end
    
    class EventAssignment < ActiveRecord::Base 
      belongs_to :user
      belongs_to :event
    end
    
    class EventAssignment::Student < EventAssignment
    end
    
    class EventAssignment::Lecturer < EventAssignment
    end
    

    我将 STI 用于 EventAssignment 模型,因为如果您对不同类型的分配有不同的逻辑,它会很有用。但是如果不需要它,只需在连接模型中使用另一个列名而不是type 来识别关系类型:

    class User < ActiveRecord::Base 
      has_many :event_assignments
      has_many :student_events, :through => :event_assignments, :source => :event, :conditions => {'event_assignments.kind' => 'student'}
      has_many :lecturer_events, :through => :event_assignments, :source => :event, :conditions => {'event_assignments.kind' => 'lecturer'}
    end
    
    class Event < ActiveRecord::Base 
      has_many :event_assignments
      has_many :students, :through => :event_assignments, :source => :user, :conditions => {'event_assignments.kind' => 'student'}
      has_many :lecturers, :through => :event_assignments, :source => :user, :conditions => {'event_assignments.kind' => 'lecturer'}
    end
    
    class EventAssignment < ActiveRecord::Base 
      belongs_to :user
      belongs_to :event
    end
    

    【讨论】:

    • 抱歉,我没有收到您的答复通知。而且,谢谢!我尝试了您的第一个解决方案。但是,Event.lecturers 和 Event.students 都返回相同的结果。我正在保存这样的讲师: event_in_db.lectures
    • 似乎第一个解决方案不起作用,因为我忘记将join_table 选项添加到Event 模型
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多