使用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
答案 0 :(得分:1)
我认为rails很难将所有这些表连接在一起。这就是你得到错误结果的原因。
基本上您正在执行以下操作:作者 - &gt;博客 - &gt;主题 - &gt;博客
如果您只是通过博客加入主题,则无需返回博客:
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