如何让一个模型服务于两个目的?

时间:2013-08-11 01:11:17

标签: ruby-on-rails

你能解释一下如何从我在Rails应用程序中创建的关联中删除重复项。该应用程序允许用户教授不同的课程,以及学习不同的课程。可供学习的课程与可以学习的课程相同。为了这个问题的目的,想象有3门课程可以教授和研究,science, math, english

我目前拥有协会的方式如下。我创建了一个Target模型(代表可用于学习的课程)并播种了三个课程science, math, english。我还创建了一个课程模型(代表用户正在教授的课程),并且播种了相同的三门课程。请注意,如果不清楚,我将模型称为“目标”,因为它代表用户试图学习的主题。

User 

has_and_belongs_to_many :targets #courses the user is studying 

has_and_belongs_to_many :courses #courses that users are teaching

因此,我认为我有一些不必要的重复。课程和目标模型将具有完全相同的数据(即相同的课程)。有没有办法创建一个模型(代替两个Target.rb和Course.rb)并用它来表示用户正在教授和学习的课程?

更新

为了帮助澄清,我只是提到种子数据来帮助解释/展示模型正在做什么,即Target.rb和Course.rb基本相同,只是扮演不同的角色。它更像是用户和目标/课程之间未来关系的模板。例如,我可能正在学习科学,但教数学。

2 个答案:

答案 0 :(得分:1)

听起来你有课程。

class Course < ActiveRecord::Base
  attr_accessible :subject
  has_and_belongs_to_many :students
  belongs_to :teacher
end

在这个设计中,一门课程可以让很多学生注册,学生可以参加任意数量的课程。每门课程都可以分配一名教师。一个课程将有一个名为subject的(字符串)属性,这个名称就像“math”或“english”。课程模型可以扩展为包含课堂编号,难度,长度等其他信息。

这将允许像

这样的查询
alice = Student.find_by_first_name("Alice")
alice.courses.last.subject
=> "english"
alice.courses.last.teacher.first_name
=> "Eric"

eric = Teacher.find_by_first_name("Eric")
eric.courses.where(subject: 'math').count
=> 3

表明Eric正在教三个数学课。

答案 1 :(得分:0)

下面的解决方案。你确定要在学生和课程之间建立一个连接 - 看起来很明显是多对多的。无论如何,重要的是第二次关联。

class User

  has_and_belongs_to_many :courses   #or possibly better has_many :through, your call
  has_many :taught_courses, :class_name => :course, :foreign_key => teacher_id

end

class Course
  belongs_to :teacher, :class_name => :user, :foreign_key => teacher_id
  has_and_belongs_to_many :users
end

更新:

上面的代码将创建两个关联。第一个是habtm关联,它需要另一个名为courses_users的表,其中包含两列(course_id和user_id,没有id列)。这会给你:

course.users       #=> list of users taking the course

如果需要,可以将此关联重命名为:

has_and_belongs_to_many :students, :class_name => :user

第二个关联是one_to_many,因此您可以通过以下方式使用它:

course.teacher         #=> return single user or nil
user.taught_courses    #=> return list of courses taught by given user

另一个更新:

通过两个表进行多个habtm关联(你可能更喜欢一个表,但是你需要使用has_many:through,这在这种情况下可能更好。 架构:

create_table "courses" do |t|
  t.string   "name"
  t.datetime "created_at", :null => false
  t.datetime "updated_at", :null => false
end

create_table "courses_students", :id => false do |t|
  t.integer "course_id"
  t.integer "user_id"
end

create_table "courses_teachers", :id => false do |t|
  t.integer "course_id"
  t.integer "user_id"
end

create_table "users" do |t|
  t.string   "name"
  t.datetime "created_at", :null => false
  t.datetime "updated_at", :null => false
end

型号:

class Course < ActiveRecord::Base
  attr_accessible :name

  has_and_belongs_to_many :teachers, :class_name => "User", :join_table => :courses_teachers
  has_and_belongs_to_many :students, :class_name => "User", :join_table => :courses_students
end

class User < ActiveRecord::Base
  attr_accessible :name

  has_and_belongs_to_many :courses, :join_table => :courses_students
  has_and_belongs_to_many :taught_corses, :join_table => :courses_teachers
end