在habtm中定义class_name时,rails中出现意外行为

时间:2014-04-24 05:21:52

标签: ruby-on-rails

我有两个模特(课程和舞者)。一门课程可以有很多舞者(学生)和老师(也是舞者)。教师可以是其他课程的学生。

我按如下方式定义表:

create_table "course_enrollments", :force => true do |t|
    t.integer    "dancer_id",     :null => false
    t.integer    "course_id",     :null => false
    t.datetime "attended_on", :null => false
end

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

create_table "courses_teachers", :id => false, :force => true do |t|
    t.integer "course_id",    :null => false
    t.integer "teacher_id", :null => false
end

create_table "dancers", :force => true do |t|
    t.string     "first_name", :null => false
    t.string     "last_name",    :null => false
    t.datetime "created_at", :null => false
    t.datetime "updated_at", :null => false
end

班级:

class Dancer < ActiveRecord::Base
    has_many :course_enrollments
    has_many :courses, :through => :course_enrollments
    has_many :teachers, :through => :courses
end

class Course < ActiveRecord::Base
    has_many :course_enrollments
    has_many :dancers, :through => :course_enrollments
    has_and_belongs_to_many :teachers, :class_name => 'Dancer'
end

class CourseEnrollment < ActiveRecord::Base
    belongs_to :dancer
    belongs_to :course
end

根据指南(http://guides.rubyonrails.org/association_basics.html),我希望Course的teachers属性能够查找表courses_teachers并使用teacher_id作为外键。相反,它正在寻找courses_dancers和dancer_id,大概是从class_name设置为'Dancer'。这是设计还是错误?如果我这样做,我可以让它工作:

has_and_belongs_to_many :teachers, :class_name => 'Dancer', :join_table => :courses_teachers

并在courses_teachers表中将teacher_id重命名为dancer_id

有更好的方法吗?

1 个答案:

答案 0 :(得分:2)

如果查看api for habtm,可以选择foreign_keyassociation_foreign_key。请尝试以下

has_and_belongs_to_many :teachers, :class_name => 'Dancer', :join_table => :courses_teachers, :foreign_key => :course_id, :association_foreign_key => :teacher_id

我不确定它是否可以在没有通过foreign_key选项的情况下工作,但它可能会在没有它的情况下尝试。