创建has_many:通过记录2次

时间:2010-05-18 01:32:57

标签: ruby-on-rails has-many-through

我有模特

class Question < ActiveRecord::Base
  WEIGHTS = %w(medium hard easy)

  belongs_to :test
  has_many :answers, :dependent => :destroy
  has_many :testing_questions
end

class Testing < ActiveRecord::Base
  belongs_to :student, :foreign_key => 'user_id'
  belongs_to :subtest
  has_many :testing_questions, :dependent => :destroy
  has_many :questions, :through => :testing_questions
end

所以,当我尝试将问题绑定到测试创建时:

>> questions = Question.all
...
>> questions.count
=> 3
>> testing = Testing.create(:user_id => 3, :subtest_id => 1, :questions => questions)
  Testing Columns (0.9ms)   SHOW FIELDS FROM `testings`                              
  SQL (0.1ms)   BEGIN                                                                
  SQL (0.1ms)   COMMIT                                                               
  SQL (0.1ms)   BEGIN                                                                
  Testing Create (0.3ms)   INSERT INTO `testings` (`created_at`, `updated_at`, `user_id`, `subtest_id`) VALUES('2010-05-18 00:53:05', '2010-05-18 00:53:05', 3, 1)                                                                                                                                                        
  TestingQuestion Columns (0.9ms)   SHOW FIELDS FROM `testing_questions`                                                                                     
  TestingQuestion Create (0.3ms)   INSERT INTO `testing_questions` (`question_id`, `created_at`, `updated_at`, `testing_id`) VALUES(1, '2010-05-18 00:53:05', '2010-05-18 00:53:05', 31)                                                                                                                                  
  TestingQuestion Create (0.4ms)   INSERT INTO `testing_questions` (`question_id`, `created_at`, `updated_at`, `testing_id`) VALUES(2, '2010-05-18 00:53:05', '2010-05-18 00:53:05', 31)                                                                                                                                  
  TestingQuestion Create (0.3ms)   INSERT INTO `testing_questions` (`question_id`, `created_at`, `updated_at`, `testing_id`) VALUES(3, '2010-05-18 00:53:05', '2010-05-18 00:53:05', 31)                                                                                                                                  
  TestingQuestion Create (0.3ms)   INSERT INTO `testing_questions` (`question_id`, `created_at`, `updated_at`, `testing_id`) VALUES(1, '2010-05-18 00:53:05', '2010-05-18 00:53:05', 31)                                                                                                                                  
  TestingQuestion Create (0.3ms)   INSERT INTO `testing_questions` (`question_id`, `created_at`, `updated_at`, `testing_id`) VALUES(2, '2010-05-18 00:53:05', '2010-05-18 00:53:05', 31)                                                                                                                                  
  TestingQuestion Create (0.3ms)   INSERT INTO `testing_questions` (`question_id`, `created_at`, `updated_at`, `testing_id`) VALUES(3, '2010-05-18 00:53:05', '2010-05-18 00:53:05', 31)                                                                                                                                  
  SQL (90.2ms)   COMMIT                                                                                                                                      
=> #<Testing id: 31, subtest_id: 1, user_id: 3, created_at: "2010-05-18 00:53:05", updated_at: "2010-05-18 00:53:05">

有6个SQL查询,并在tests_questions中创建了6个记录。为什么?

5 个答案:

答案 0 :(得分:2)

我创建了一个非常简单的例子来处理你的例子:

class Question < ActiveRecord::Base
  has_many :testing_questions
end

class Testing < ActiveRecord::Base
  has_many :testing_questions
  has_many :questions, :through => :testing_questions
end

class TestingQuestion < ActiveRecord::Base
  belongs_to :question
  belongs_to :testing
end

..然后我可以执行以下操作,并且不会创建重复记录:

Loading development environment (Rails 2.3.5)
>> q1 = Question.new
=> #<Question id: nil, title: nil, ask: nil, created_at: nil, updated_at: nil>
>> q1.title = "Dit is de eerste vraag"
=> "Dit is de eerste vraag"
>> q2 = Question.new
=> #<Question id: nil, title: nil, ask: nil, created_at: nil, updated_at: nil>
>> q2.title = "Dit is de tweede vraag"
=> "Dit is de tweede vraag"
>> q1.save
=> true
>> q2.save
=> true
>> tt = Testing.new
=> #<Testing id: nil, name: nil, description: nil, action: nil, created_at: nil, updated_at: nil>
>> tt.questions
=> []
>> tt.name = "Test1"
=> "Test1"
>> tt.questions << q1
=> [#<Question id: 1, title: "Dit is de eerste vraag", ask: nil, created_at:   "2010-05-18 19:40:54", updated_at: "2010-05-18 19:40:54">]
>> tt.questions << q2
=> [#<Question id: 1, title: "Dit is de eerste vraag", ask: nil, created_at: "2010-05-18 19:40:54", updated_at: "2010-05-18 19:40:54">, #<Question id: 2, title: "Dit is de tweede vraag", ask: nil, created_at: "2010-05-18 19:40:59", updated_at: "2010-05-18 19:40:59">]
>> tt.testing_questions
=> []
>> tt.save
=> true
>> tt.testing_questions
=> [#<TestingQuestion id: 1, question_id: 1, testing_id: 1, extra_info: nil, created_at: "2010-05-18 19:41:43", updated_at: "2010-05-18 19:41:43">, #<TestingQuestion id: 2, question_id: 2, testing_id: 1, extra_info: nil, created_at: "2010-05-18 19:41:43", updated_at: "2010-05-18 19:41:43">]
>>

实际上除了TestingQuestion(你没有展示)之外,它与你的完全相同。这有帮助吗?

答案 1 :(得分:0)

第一个问题可能是您的联接表的命名

testing_questions

Rails期望连接表的名称是按字母顺序的两个表名的串联

question_testings

答案 2 :(得分:0)

查看表结构,它是表之间的has_and_belongs_to_many关系,不需要在这里使用has_many和through选项,因为您的连接表将不具有模型(除了id之外不存在额外的列)。无需为连接表创建模型。

所以,我建议你改变你的模型


class Question < ActiveRecord::Base
WEIGHTS = %w(medium hard easy) belongs_to :test
has_many :answers, :dependent => :destroy
has_and_belongs_to_many :question_testings end

class Testing < ActiveRecord::Base
belongs_to :student, :foreign_key => 'user_id' belongs_to :subtest has_and_belongs_to_many :question_testings end

请将您的表名更改为question_testings。

请查看此链接以获取更多信息http://guides.rubyonrails.org/association_basics.html#choosing-between-has-many-through-and-has-and-belongs-to-many

答案 3 :(得分:0)

如果不查看Rails源代码或尝试解决,我建议尝试从Question类中删除“has_many:testing_questions”或者在那里添加has_many ...:。刚才Rails只是与连接表有关系,而不是那边的“真实”目标。

连接表的名称不应该在这里引起任何问题。

答案 4 :(得分:0)

您的questions数组包含3个项目。当您创建Testing实例并指定使用:questions => questions创建它时,它会将它们添加到questions关系,但由于此关系是通过另一个关系,因此必须将它们添加到另一个是第一个,导致它们被插入两次。通常,您会有一些其他模型表示连接表,因此您有3个记录插入到Questions表中,还有3个记录插入到TestingQuestions连接表中(has_many:through)。

在我看来,这是你如何定义你没有展示过的TestingQuestions模型的问题。例如,它是否指向与问题模型相同的表?