Skip to content

Commit

Permalink
update foreword/preface example
Browse files Browse the repository at this point in the history
  • Loading branch information
ezekg committed Aug 12, 2024
1 parent 89d1463 commit d1cd47d
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 33 deletions.
34 changes: 21 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,25 +54,30 @@ class Book < ActiveRecord::Base
has_many :coauthorships
has_many :coauthors, through: :coauthorships, source: :user

# editors for the book via a join table
has_many :edits
has_many :editors, through: :edits, source: :user
# prefacers for the book via a join table
has_many :prefaces
has_many :prefacers, through: :prefaces, source: :user

# prefacers for the book via a join table
has_many :forewords
has_many :foreworders, through: :forewords, source: :user

# illustrators for the book via a join table
has_many :illustrations
has_many :illustrators, through: :illustrations, source: :user

# foreword writers for the book via a join table
has_many :forewords
has_many :prefacers, through: :forewords, source: :user
# editors for the book via a join table
has_many :edits
has_many :editors, through: :edits, source: :user

# union association for all contributors to the book
has_many :contributors, class_name: 'User', union_of: %i[
has_many :contributors, -> { distinct }, class_name: 'User', union_of: %i[
author
coauthors
editors
illustrators
foreworders
prefacers
illustrators
editors
]
end
```
Expand All @@ -89,14 +94,17 @@ writer = User.create(name: 'Ray Bradbury')
# create book by the author
book = Book.create(title: 'I, Robot', author:)

# assign an editor
Edit.create(user: editor, book:)
# assign a preface by the author
Preface.create(user: author, book:)

# assign a foreword writer
Foreword.create(user: writer, book:)

# assign an illustrator
Illustration.create(user: illustrator, book:)

# assign a foreword writer
Foreword.create(user: writer, book:)
# assign an editor
Edit.create(user: editor, book:)

# access all contributors (author, editor, illustrator, etc.)
book.contributors.to_a
Expand Down
58 changes: 38 additions & 20 deletions spec/union_of_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1340,6 +1340,11 @@ def owned = where(owner: proxy_association.owner)
t.integer :user_id
end

temporary_table :prefaces do |t|
t.integer :book_id
t.integer :user_id
end

temporary_model :user do
has_many :books
has_many :coauthorships
Expand Down Expand Up @@ -1368,33 +1373,36 @@ def owned = where(owner: proxy_association.owner)
belongs_to :user
end

temporary_model :preface do
belongs_to :book
belongs_to :user
end

temporary_model :book do
# the primary author of the book
belongs_to :author, class_name: 'User', foreign_key: 'author_id', optional: true

# coauthors of the book via a join table
has_many :coauthorships
has_many :coauthors, through: :coauthorships, source: :user

# editors for the book via a join table
has_many :edits
has_many :editors, through: :edits, source: :user
has_many :prefaces
has_many :prefacers, through: :prefaces, source: :user

has_many :forewords
has_many :foreworders, through: :forewords, source: :user

# illustrators for the book via a join table
has_many :illustrations
has_many :illustrators, through: :illustrations, source: :user

# foreword writers for the book via a join table
has_many :forewords
has_many :prefacers, through: :forewords, source: :user
has_many :edits
has_many :editors, through: :edits, source: :user

# union association for all contributors to the book
has_many :contributors, class_name: 'User', union_of: %i[
has_many :contributors, -> { distinct }, class_name: 'User', union_of: %i[
author
coauthors
editors
illustrators
foreworders
prefacers
illustrators
editors
]
end

Expand All @@ -1405,9 +1413,10 @@ def owned = where(owner: proxy_association.owner)
let(:book) {
book = Book.create(title: 'I, Robot', author:)

Edit.create(user: editor, book:)
Illustration.create(user: illustrator, book:)
Preface.create(user: author, book:)
Foreword.create(user: writer, book:)
Illustration.create(user: illustrator, book:)
Edit.create(user: editor, book:)

book
}
Expand All @@ -1427,7 +1436,7 @@ def owned = where(owner: proxy_association.owner)
it 'should use UNION' do
expect(book.contributors.to_sql).to match_sql <<~SQL.squish
SELECT
users.*
DISTINCT users.*
FROM
users
WHERE
Expand Down Expand Up @@ -1460,9 +1469,18 @@ def owned = where(owner: proxy_association.owner)
SELECT
users.id
FROM
users INNER JOIN edits ON users.id = edits.user_id
users INNER JOIN forewords ON users.id = forewords.user_id
WHERE
edits.book_id = 1
forewords.book_id = 1
)
UNION
(
SELECT
users.id
FROM
users INNER JOIN prefaces ON users.id = prefaces.user_id
WHERE
prefaces.book_id = 1
)
UNION
(
Expand All @@ -1478,9 +1496,9 @@ def owned = where(owner: proxy_association.owner)
SELECT
users.id
FROM
users INNER JOIN forewords ON users.id = forewords.user_id
users INNER JOIN edits ON users.id = edits.user_id
WHERE
forewords.book_id = 1
edits.book_id = 1
)
) users
)
Expand Down

0 comments on commit d1cd47d

Please sign in to comment.