#ruby-on-rails
#ruby-on-rails
Вопрос:
При загрузке ассоциаций с использованием has_many :through
, как показано в примере кода ниже (автономный / выполняемый), приводит к неожиданной загрузке записей, как показано в сбое утверждения. Я не уверен, чего не хватает для прохождения теста.
unless File.exist?('Gemfile')
File.write('Gemfile', <<-GEMFILE)
source 'https://rubygems.org'
gem 'rails', '4.1.4'
gem 'sqlite3'
GEMFILE
system 'bundle'
end
require 'bundler'
Bundler.setup(:default)
require 'active_record'
require 'minitest/autorun'
require 'logger'
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table "blogs" do |t|
t.integer :subject_id
t.integer :author_id
end
create_table "subjects"
create_table "authors"
end
class Subject < ActiveRecord::Base
has_many :blogs, dependent: :destroy
end
class Blog < ActiveRecord::Base
belongs_to :subject
belongs_to :author
end
class Author < ActiveRecord::Base
has_many :all_blogs_with_subject, through: :subjects, source: :blogs
has_many :blogs
has_many :subjects, through: :blogs
end
class HasManyThroughLoadTest < Minitest::Test
def test_loading_associations_via_has_many_through
author_one = Author.create!
author_two = Author.create!
Subject.create!(blogs: [Blog.new(author: author_one), Blog.new(author: author_one)])
Subject.create!(blogs: [Blog.new(author: author_one), Blog.new(author: author_two)])
# Expected 1, Actual 2 (also includes author_one's blog)
assert_equal 1, author_two.reload.all_blogs_with_subject.size
# Expected 3, Actual 4 (also includes author_two's blog)
assert_equal 3, author_one.reload.all_blogs_with_subject.uniq.size
end
end
Ответ №1:
Я думаю, rails с трудом объединяет все эти таблицы вместе. Вот почему вы получаете неправильные результаты.
В основном вы делаете следующее: Автор -> Блог -> Тема -> Блог
На самом деле вам не нужно возвращаться в блог, если вы просто присоединитесь к теме с помощью blog:
class Blog < ActiveRecord::Base
belongs_to :subject
belongs_to :author
scope :with_subject, -> { joins(:subject) }
end
class HasManyThroughLoadTest < Minitest::Test
def test_loading_associations_via_has_many_through
author_one = Author.create!
author_two = Author.create!
Subject.create!(blogs: [Blog.new(author: author_one), Blog.new(author: author_one)])
Subject.create!(blogs: [Blog.new(author: author_one), Blog.new(author: author_two)])
# Expected 1, Actual 2 (also includes author_one's blog)
assert_equal 1, author_two.reload.blogs.with_subject.size
# Expected 3, Actual 4 (also includes author_two's blog)
assert_equal 3, author_one.reload.blogs.with_subject.uniq.size
end
end
Комментарии:
1. Да, последнее утверждение должно быть 3, а не 2. Обновлен вопрос.