versions
rails: (4.0.0)
ruby: (2.0.0)
mongoid (4.0.0)
activemodel (~> 4.0.0)
moped (~> 2.0.beta5)
problem
I have an interface where I create a book by submitting an ISBN and a list of authors. My aim is to avoid duplicate book records, and to ensure that all the authors I've EVER added to a book with a specific ISBN get added to the original book, and that the new book does not actually get created.
I have a class that looks very similar to the book class below, and I've written some tests which I've also included below. I think the tests are correct for my purposes but please enlighten me if they're not testing what I think they are.
edit: These tests are not currently passing, so I must be doing something wrong somewhere. Are the tests written wrongly?
edit 2: I've commented in the specs to try to explain what the problems I'm facing are. There are a couple of failing tests and I don't understand what exactly is wrong.
edit 3: I've removed the extra specs, keeping only the specs that are failing
This is not the actual problem, but a generalised-ish version of it.
book class
class Book
include Mongoid::Document
include Mongoid::Timestamps
before_create :add_authors_to_existing_book_if_present
has_and_belongs_to_many :authors
field :isbn, type: String
validates_uniqueness_of :isbn
def add_authors_to_existing_book_if_present
if existing_book
existing_book.authors << self.authors
self.authors = []
existing_book.save!
# returns false to stop the model from
# being created if existing_book is truthy
false
end
end
def existing_book
Book.where(isbn: isbn).first
end
end
author class
class Author
include Mongoid::Document
include Mongoid::Timestamps
has_and_belongs_to_many :books
field :name, type: String
end
model rspec tests
describe "#add_authors_to_existing_book_if_present" do
context "when the book already exists in another author" do
let(:first_author) { Author.new(name: "First", books: [first_book]) }
let(:second_author) { Author.new(name: "Second", books: [second_book]) }
let(:first_book) { Book.new(isbn: "12345") }
let(:second_book) { Book.new(isbn: "12345") }
before do
first_author.save
second_author.save
end
# fails
it "only adds the first book to the second author" do
expect(second_author.books).to eq [first_book]
expect(second_author.books).not_to eq [second_book]
end
# this almost passes, but the author_ids in first_book is empty
# fails
it "assigns the second author to the first book" do
expect(first_book.authors).to eq [first_author, second_author]
end
# only the first_author is part of the array
end
end