I am fairly new to coding and I am trying to set up a Rails 5 backend for a new application. I have created a many-to-many relationship between two models, Projects and Skills, that both use S3 storage from Amazon Web Services to attach an image.
I can make a GET request for each model and see working image URLs in the json response, but when I try to include, say, Skills inside the GET request for a Project, I receive the Skill without the image URL.
Here is some sample json I get from calling the Skill "HTML":
created_at: "2019-12-06T04:27:52.537Z"
id: 4
image: (working URL for skill image)
name: "HTML"
updated_at: "2019-12-06T04:27:52.540Z"
And here is json for a Project with the Skill "HTML" nested inside it:
created_at: "2019-12-07T15:11:32.592Z"
id: 53
image: (working URL for project image)
skills: Array(1)
0:
created_at: "2019-12-06T04:27:52.537Z"
id: 4
name: "HTML"
updated_at: "2019-12-06T04:27:52.540Z"
__proto__: Object
length: 1
__proto__: Array(0)
title: "Card Game"
updated_at: "2019-12-07T19:35:08.751Z"
As you can see, the Skill "HTML" is suddenly missing the corresponding image URL when it is nested.
Here is my basic setup for the Projects Controller:
class ProjectsController < ApplicationController
def index
@projects = Project.all
render json: @projects, include: :categories
end
And here is my Skills Serializer:
class SkillSerializer < ActiveModel::Serializer
attributes :id, :name, :created_at, :updated_at, :image
def image
object.image.service_url if object.image.attached?
end
end
Does anyone know how to include a web-storage URL that belongs to a model when it is included inside another model association?
Changed the Projects Controller to the following:
class ProjectsController < ApplicationController
include Rails.application.routes.url_helpers
def index
@projects = Project.all
projects_with_images = @projects.map do |project|
new_project = project.attributes.symbolize_keys
new_project[:image] = rails_blob_path(project.image, only_path: true)
skills = project.skills
skills_with_images = skills.map do |skill|
new_skill = skill.attributes.symbolize_keys
new_skill[:image] = rails_blob_path(skill.image, only_path: true)
new_skill
end
new_project[:skills] = skills_with_images
new_project
end
render json: {projects: projects_with_images}
end
May not be the most efficient, but it seems to be working!
Here's a boiled down version from my show route for making sure a model has it's image url attached:
def show
@project = Project.find(params[:id])
project_with_image = @project.attributes.symbolize_keys
project_with_image[:image] = rails_blob_path(@project.image, only_path: true)
render json: project_with_image