Вы можете включить ассоциации с опцией :include
при вызове as_json
.
render json: @posts.as_json(include: :images)
Вы можете ограничить это одним изображением, добавив новую ассоциацию к Post
.
class Post < ApplicationRecord
has_many :images
has_one :showcase_image, class_name: 'Image'
end
Это позволит вам вместо этого использовать :showcase_image
.
render json: @posts.as_json(include: :showcase_image)
Вы также можете использовать Jbuilder для решения проблемы в hand без добавления дополнительной ассоциации.
# app/views/posts/index.json.jbuilder
# Get images that belong to posts, group them by post_id and
# return the minimum image id for each post_id.
images = Images.where(post_id: @posts.select(:id)).group(:post_id).minimum(:id)
# Request the full image data for all image ids returned above.
images = images.keys.zip(Image.find(images.values)).to_h
json.array! @posts do |post|
json.extract! post, :id, :title, :body, :...
json.showcase_image do
image = images[post.id]
if image
json.extract! image, :id, :name, :location, :...
else
json.null!
end
end
end
Без вызова специфицированного рендера c Rails по умолчанию будет использовать файл app/views/posts/index
и выберет файл, соответствующий запросу. (Если вы запрашиваете HTML, он ищет файл HTML, если вы запрашиваете JSON, он ищет JSON, et c.)
# app/controllers/posts_controller.rb
class PostsController < ApplicationController
def index
@posts = Post.all
end
end
Теперь, когда вы запрашиваете /posts.json
или /posts
с заголовком Accept: application/json
ваше приложение должно вернуть сборку ответа JSON от Jbuilder.