Rails 3 - has_and_belongs_to_many

时间:2012-03-30 14:06:28

标签: ruby-on-rails ruby migration model-associations

我有2个模型 - 教师主题。想要通过名称资格认证的加入表连接它们。

看起来我做错了什么:

class Teacher < ActiveRecord::Base
  has_and_belongs_to_many :subjects, :join_table => "Qualification"
end

class Subject < ActiveRecord::Base 
  has_and_belongs_to_many :teachers, :join_table => "Qualification"
end

我的迁移:

class CreateQualificationJoinTable < ActiveRecord::Migration
  def change
    create_table :qualification, :id => false do |t|
      t.integer :subject_id
      t.integer :teacher_id
    end
    add_index :qualification, :subject_id
    add_index :qualification, :teacher_id
  end
end

当我打开rails console并打印时,例如

ruby-1.9.3-head :013 > Qualification

我明白了:

NameError: uninitialized constant Qualification
    from (irb):13
    from /Users/serg/.rvm/gems/ruby-1.9.3-head/gems/railties-3.2.0/lib/rails/commands/console.rb:47:in `start'
    from /Users/serg/.rvm/gems/ruby-1.9.3-head/gems/railties-3.2.0/lib/rails/commands/console.rb:8:in `start'
    from /Users/serg/.rvm/gems/ruby-1.9.3-head/gems/railties-3.2.0/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

有什么问题?

3 个答案:

答案 0 :(得分:3)

首先,在迁移中创建表不会定义您的模型。您必须在Qualification中创建app/models/qualification.rb模型:

class Qualification < ActiveRecord::Base
  belongs_to :subjects
  belongs_to :teachers
end

其次,如果您使用的是Rails 3,请抛弃has_and_belongs_to_many并使用has_many :through

class Teacher < ActiveRecord::Base
  has_many :qualifications
  has_many :subjects, :through => :qualifications
end

class Subject < ActiveRecord::Base 
  has_many :qualifications
  has_many :teachers, :through => :qualifications
end

答案 1 :(得分:1)

如果您不打算直接使用连接表,则应该只使用has_and_belongs_to_many。在您的情况下,如果您不打算使用Qualification本身但仅使用Teacher和Subject,并使用Active Record执行脏工作,请使用它。如果您与连接模型有任何关系,请使用has_many:through。

在此处阅读更多内容:Choosing Between has_many :through and has_and_belongs_to_many

答案 2 :(得分:0)

在rails 3中,最好的方法是通过迁移进行中间表资格认证

属性将类似于此表

subject_id:整数    teacher_id:整数

也可以像这样进行资格认证

class Qualification < ActiveRecord::Base
  has_many :subjects
  has_many :teachers
end

然后定义其他两个模型,如

 class Teacher < ActiveRecord::Base
   has_many :qualifications
   has_many :subjects, :through => :qualifications
 end

 class Subject < ActiveRecord::Base 
  has_many :qualifications
  has_many :teachers, :through => :qualifications
 end

并仔细阅读此链接

   http://blog.hasmanythrough.com/2007/1/15/basic-rails-association-cardinality