I'm trying to write my test to ensure creating a new book
with genres
assigned to it works.
I am using Active Model Serializer with the JSON_API structure (http://jsonapi.org/)
class Book < ApplicationRecord
belongs_to :author, class_name: "User"
has_and_belongs_to_many :genres
end
class Genre < ApplicationRecord
has_and_belongs_to_many :books
end
class BookSerializer < ActiveModel::Serializer
attributes :id, :title, :adult_content, :published
belongs_to :author
has_many :genres
end
def setup
...
@fantasy = genres(:fantasy)
@newbook = {
title: "Three Little Pigs",
adult_content: false,
author_id: @jim.id,
published: false,
genres: [{title: 'Fantasy'}]
}
end
test "book create - should create a new book" do
post books_path, params: @newbook, headers: user_authenticated_header(@jim)
assert_response :created
json = JSON.parse(response.body)
puts "json = #{json}"
assert_equal "Three Little Pigs", json['data']['attributes']['title']
genre_data = json['data']['relationships']['genres']['data']
puts "genre_data = #{genre_data.count}"
assert_equal "Fantasy", genre_data
end
def book_params
params.permit(:title, :adult_content, :published, :author_id, :genres)
end
# Running:
......................................................json = {"data"=>{"id"=>"1018350796", "type"=>"books", "attributes"=>{"title"=>"Three Little Pigs", "adult-content"=>false, "published"=>false}, "relationships"=>{"author"=>{"data"=>{"id"=>"1027431151", "type"=>"users"}}, "genres"=>{"data"=>[]}}}}
genre_data = 0
F
Failure:
BooksControllerTest#test_book_create_-_should_create_a_new_book [/Users/warlock/App_Projects/Raven Quill/Source Code/Rails/raven-quill-api/test/controllers/books_controller_test.rb:60]:
Expected: "Fantasy"
Actual: []
bin/rails test test/controllers/books_controller_test.rb:51
Finished in 1.071044s, 51.3518 runs/s, 65.3568 assertions/s.
55 runs, 70 assertions, 1 failures, 0 errors, 0 skips
As you can see from my JSON console log, it appears my genres are not being set(need to scroll to the right in the test output above).
Please ignore this line:
assert_equal "Fantasy", genre_data
I know that's wrong. At the moment, the json is showing genre => {data: []}
(empty array), that's the thing I'm trying to solve at the moment.
How do I go about creating a book with genres in this case, any ideas? :D
This is just sad...third time this week, I am answering my own question.
I finally found the answer from this Stackoverflow question:
HABTM association with Strong Parameters is not saving user in Rails 4
Turns out my strong parameters need to be:
def book_params
params.permit(:title, :adult_content, :published, :author_id, {:genre_ids => []})
end
Then my test data can be:
@fantasy = genres(:fantasy)
@newbook = {
title: "Three Little Pigs",
adult_content: false,
author_id: @jim.id,
published: false,
genre_ids: [@fantasy.id]
}
Update my test method to:
test "book create - should create a new book" do
post books_path, params: @newbook, headers: user_authenticated_header(@jim)
assert_response :created
json = JSON.parse(response.body)
assert_equal "Three Little Pigs", json['data']['attributes']['title']
genre = json['data']['relationships']['genres']['data'].first['title']
assert_equal "Fantasy", genre
end
Now my test passes.