I have an api request where Im getting the provider data for each movie. Im iterating over it and when I do provider['provider_name'] it gives me a list of providers for each movie which is great. As soon as i put this into the Content.create method it gives nil. If I move the entire each statement within the create method I end up with just the full hash/array. Not really sure where to go with this one.
movie_url = 'https://api.themoviedb.org/3/trending/movie/week?api_key=API_KEY&language=en-US'
2.times do |m|
contents = JSON.parse(URI.open("#{movie_url}&page=#{m 1}").read)['results']
contents.each do |content|
base_poster_url = 'https://image.tmdb.org/t/p/original'
results = JSON.parse(URI.open("https://api.themoviedb.org/3/movie/#{content['id']}/watch/providers?api_key=API_KEY&language=en-US&watch_region=GB").read)['results']
if results != {} && results["GB"] && results['GB']["flatrate"]
results['GB']['flatrate'].each do |provider|
p provider["provider_name"]
Content.create(
imdb_id: content['id'],
title: content['original_title'],
description: content['overview'],
poster: "#{base_poster_url}#{content['poster_path']}",
rating: content['vote_average'],
content_type: content['media_type'],
streaming_services: nil
)
end
puts "content created for movie: #{content['original_title']}"
end
end
end
The output of p provider["provider_name]
in terminal looks like:
content created for movie: Chip 'n Dale: Rescue Rangers
"Sky Go"
"Now TV Cinema"
"Virgin TV Go"
content created for movie: Top Gun
"Virgin TV Go"
content created for movie: Uncharted
"Virgin TV Go"
If I move the provider[provider_name"]
into the Content.create method so like this
streaming_services: provider["provider_name"]
The database output looks like this:
content_type: "movie",
streaming_services: []
The api request file looks like this
"results": {
GB": {
"link": "https://www.themoviedb.org/movie/744-top-gun/watch?locale=GB",
"buy": [
{
"display_priority": 2,
"logo_path": "/peURlLlr8jggOwK53fJ5wdQl05y.jpg",
"provider_id": 2,
"provider_name": "Apple iTunes"
},
{
"display_priority": 3,
"logo_path": "/tbEdFQDwx5LEVr8WpSeXQSIirVq.jpg",
"provider_id": 3,
"provider_name": "Google Play Movies"
},
{
"display_priority": 8,
"logo_path": "/5GEbAhFW2S5T8zVc1MNvz00pIzM.jpg",
"provider_id": 35,
"provider_name": "Rakuten TV"
},
{
"display_priority": 8,
"logo_path": "/2pCbao1J9s0DMak2KKnEzmzHni8.jpg",
"provider_id": 130,
"provider_name": "Sky Store"
},
{
"display_priority": 10,
"logo_path": "/mT9kIe6JVz72ikWJ58x0q8ckUW3.jpg",
"provider_id": 40,
"provider_name": "Chili"
},
{
"display_priority": 11,
"logo_path": "/5NyLm42TmCqCMOZFvH4fcoSNKEW.jpg",
"provider_id": 10,
"provider_name": "Amazon Video"
},
{
"display_priority": 13,
"logo_path": "/oIkQkEkwfmcG7IGpRR1NB8frZZM.jpg",
"provider_id": 192,
"provider_name": "YouTube"
},
{
"display_priority": 48,
"logo_path": "/shq88b09gTBYC4hA7K7MUL8Q4zP.jpg",
"provider_id": 68,
"provider_name": "Microsoft Store"
}
],
"flatrate": [
{
"display_priority": 8,
"logo_path": "/fBHHXKC34ffxAsQvDe0ZJbvmTEQ.jpg",
"provider_id": 29,
"provider_name": "Sky Go"
},
{
"display_priority": 62,
"logo_path": "/nqGY5wuSv14vbY7NYOs8stJ6ZBF.jpg",
"provider_id": 591,
"provider_name": "Now TV Cinema"
},
{
"display_priority": 63,
"logo_path": "/o6li3XZrBKXSqyNRS39UQEfPTCH.jpg",
"provider_id": 594,
"provider_name": "Virgin TV Go"
}
],
"rent": [
{
"display_priority": 2,
"logo_path": "/peURlLlr8jggOwK53fJ5wdQl05y.jpg",
"provider_id": 2,
"provider_name": "Apple iTunes"
},
{
"display_priority": 3,
"logo_path": "/tbEdFQDwx5LEVr8WpSeXQSIirVq.jpg",
"provider_id": 3,
"provider_name": "Google Play Movies"
},
{
"display_priority": 8,
"logo_path": "/2pCbao1J9s0DMak2KKnEzmzHni8.jpg",
"provider_id": 130,
"provider_name": "Sky Store"
},
{
"display_priority": 8,
"logo_path": "/5GEbAhFW2S5T8zVc1MNvz00pIzM.jpg",
"provider_id": 35,
"provider_name": "Rakuten TV"
},
{
"display_priority": 10,
"logo_path": "/mT9kIe6JVz72ikWJ58x0q8ckUW3.jpg",
"provider_id": 40,
"provider_name": "Chili"
},
{
"display_priority": 11,
"logo_path": "/5NyLm42TmCqCMOZFvH4fcoSNKEW.jpg",
"provider_id": 10,
"provider_name": "Amazon Video"
},
{
"display_priority": 13,
"logo_path": "/oIkQkEkwfmcG7IGpRR1NB8frZZM.jpg",
"provider_id": 192,
"provider_name": "YouTube"
},
{
"display_priority": 48,
"logo_path": "/shq88b09gTBYC4hA7K7MUL8Q4zP.jpg",
"provider_id": 68,
"provider_name": "Microsoft Store"
}
]
},
}
Not sure what Im doing wrong and have attempted to access it in a few different ways using map, split, flatten. Sometimes with small successes. .split(",") actually gave me arrays however only one array per movie and some have multiple providers. Im sure there is a better way.
CodePudding user response:
I suppose you need to move creating of Content
out of the loop like this:
movie_url = 'https://api.themoviedb.org/3/trending/movie/week?api_key=API_KEY&language=en-US'
2.times do |m|
contents = JSON.parse(URI.open("#{movie_url}&page=#{m 1}").read)['results']
contents.each do |content|
base_poster_url = 'https://image.tmdb.org/t/p/original'
results = JSON.parse(URI.open("https://api.themoviedb.org/3/movie/#{content['id']}/watch/providers?api_key=API_KEY&language=en-US&watch_region=GB").read)['results']
Content.create(
imdb_id: content['id'],
title: content['original_title'],
description: content['overview'],
poster: "#{base_poster_url}#{content['poster_path']}",
rating: content['vote_average'],
content_type: content['media_type'],
streaming_services: results.dig("GB", "flatrate")&.map { |provider| provider["provider_name"] }
)
end
end
Note: If streaming_services
type is array then leave as it is. If string then add join(', ')
in the end streaming_services: results.dig("GB", "flatrate")&.map { |provider| provider["provider_name"] }&.join(', ')