@@ -1340,6 +1340,11 @@ def owned = where(owner: proxy_association.owner)
13401340 t . integer :user_id
13411341 end
13421342
1343+ temporary_table :prefaces do |t |
1344+ t . integer :book_id
1345+ t . integer :user_id
1346+ end
1347+
13431348 temporary_model :user do
13441349 has_many :books
13451350 has_many :coauthorships
@@ -1368,33 +1373,36 @@ def owned = where(owner: proxy_association.owner)
13681373 belongs_to :user
13691374 end
13701375
1376+ temporary_model :preface do
1377+ belongs_to :book
1378+ belongs_to :user
1379+ end
1380+
13711381 temporary_model :book do
1372- # the primary author of the book
13731382 belongs_to :author , class_name : 'User' , foreign_key : 'author_id' , optional : true
13741383
1375- # coauthors of the book via a join table
13761384 has_many :coauthorships
13771385 has_many :coauthors , through : :coauthorships , source : :user
13781386
1379- # editors for the book via a join table
1380- has_many :edits
1381- has_many :editors , through : :edits , source : :user
1387+ has_many :prefaces
1388+ has_many :prefacers , through : :prefaces , source : :user
1389+
1390+ has_many :forewords
1391+ has_many :foreworders , through : :forewords , source : :user
13821392
1383- # illustrators for the book via a join table
13841393 has_many :illustrations
13851394 has_many :illustrators , through : :illustrations , source : :user
13861395
1387- # foreword writers for the book via a join table
1388- has_many :forewords
1389- has_many :prefacers , through : :forewords , source : :user
1396+ has_many :edits
1397+ has_many :editors , through : :edits , source : :user
13901398
1391- # union association for all contributors to the book
1392- has_many :contributors , class_name : 'User' , union_of : %i[
1399+ has_many :contributors , -> { distinct } , class_name : 'User' , union_of : %i[
13931400 author
13941401 coauthors
1395- editors
1396- illustrators
1402+ foreworders
13971403 prefacers
1404+ illustrators
1405+ editors
13981406 ]
13991407 end
14001408
@@ -1405,9 +1413,10 @@ def owned = where(owner: proxy_association.owner)
14051413 let ( :book ) {
14061414 book = Book . create ( title : 'I, Robot' , author :)
14071415
1408- Edit . create ( user : editor , book :)
1409- Illustration . create ( user : illustrator , book :)
1416+ Preface . create ( user : author , book :)
14101417 Foreword . create ( user : writer , book :)
1418+ Illustration . create ( user : illustrator , book :)
1419+ Edit . create ( user : editor , book :)
14111420
14121421 book
14131422 }
@@ -1427,7 +1436,7 @@ def owned = where(owner: proxy_association.owner)
14271436 it 'should use UNION' do
14281437 expect ( book . contributors . to_sql ) . to match_sql <<~SQL . squish
14291438 SELECT
1430- users.*
1439+ DISTINCT users.*
14311440 FROM
14321441 users
14331442 WHERE
@@ -1460,9 +1469,18 @@ def owned = where(owner: proxy_association.owner)
14601469 SELECT
14611470 users.id
14621471 FROM
1463- users INNER JOIN edits ON users.id = edits .user_id
1472+ users INNER JOIN forewords ON users.id = forewords .user_id
14641473 WHERE
1465- edits.book_id = 1
1474+ forewords.book_id = 1
1475+ )
1476+ UNION
1477+ (
1478+ SELECT
1479+ users.id
1480+ FROM
1481+ users INNER JOIN prefaces ON users.id = prefaces.user_id
1482+ WHERE
1483+ prefaces.book_id = 1
14661484 )
14671485 UNION
14681486 (
@@ -1478,9 +1496,9 @@ def owned = where(owner: proxy_association.owner)
14781496 SELECT
14791497 users.id
14801498 FROM
1481- users INNER JOIN forewords ON users.id = forewords .user_id
1499+ users INNER JOIN edits ON users.id = edits .user_id
14821500 WHERE
1483- forewords .book_id = 1
1501+ edits .book_id = 1
14841502 )
14851503 ) users
14861504 )
0 commit comments