Creating has_many :through records 2x times
I have models
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
So when I try to bind questions to testing on it's creation:
>> 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">
There are 6 SQL queries and 6 records in testing_questions are created. Why?
I have created a very simple example that handles your example:
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
.. and then i can just do the following, and no duplicate records are created:
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">]
>>
Actually that is completely the same as you have, except for the TestingQuestion (which you didn't show). Does that help?
A first issue could be the naming of your join table
testing_questions
Rails expects the join table’s name to be a concatenation of the two table names in alphabetical order
question_testings
Looking at the table structure it is a has_and_belongs_to_many relations between the tables, there is no need to use has_many and through option here as your join table will not be having a model( no extra columns other than ids are present). No need to create a model for join table.
So, I suggest to change your models like this
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
and please change your table name as question_testings.
Please have a look at this link for more info http://guides.rubyonrails.org/association_basics.html#choosing-between-has-many-through-and-has-and-belongs-to-many
Without looking at the Rails source or trying around, I'd suggest to try either removing the "has_many :testing_questions" from the Question class or add a has_many ... :through there. Just now Rails just has a relation to the join table, but not to the "real" target from that side.
The name of the join table shouldn't cause any problems here.
Your questions
array contains 3 items. When you create a Testing
instance and specify to create it with :questions => questions
it is going to add them to the questions
relationship, but because this relationship is through another one, they must be added to the other one first, resulting in them being inserted twice. Typically, you would have some other model representing the join table, so that you have 3 records inserted into the Questions table and also 3 into the TestingQuestions join table (has_many :through).
Looks to me like its an issue in how you have defined your TestingQuestions model, which you have not shown. For example, is it pointing to the same table as the Questions model?
精彩评论