Rails - 如何获取关联 table 的第一条记录?

Rails - How get first record of associated table?

我正在尝试为我的移动应用创建一个 api。

我有 postsimages table。对于我的 api,我可以发送所有 posts

@posts = Post.all render json: @posts

Output: [{"id":20,"title":"Title 1", "body":" first post ", "user_id":1 }]

但它根本不包含图像。为了在我的应用程序主页中显示展示图片,我只需要关联图片的第一张图片。

我需要的输出是(showcase_image 属性的名称无关紧要):

Output: [{"id":20, "title":"Title 1", "body":" first post ", "showcase_image": 'first_image.jpg' , "user_id":1 }]

我需要将关联图片 table 中的第一张图片添加到我的 json 回复中..

提前致谢!

我建议使用序列化程序。 Active Model Serializer is pretty standard and easy to use, but is not receiving any updates and has a bad performance. You can choose any other serializer (I recommend Blueprinter) 或使用 AMS。 通过 AMS,您可以定义要序列化的关系,它将构建您期望的 json

class PostSerializer < ActiveModel::Serializer
  attributes :id, :title, :body, :showcase_image, :user_id

  def showcase_image
    object.images.first.name # don't know what is the attribute you're looking for
  end
end

在你的控制器上:

@posts = Post.includes(:images).all # Use includes to avoid N+1 problems
render json: @posts, serialize_collection: PostSerializer

您可以在调用 as_json 时包含与 :include 选项的关联。

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 来解决手头的问题,而无需添加额外的关联。

# 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

不调用特定的渲染,Rails 将默认为 app/views/posts/index 文件,select 匹配请求的文件。 (如果你请求 HTML 它会寻找一个 HTML 文件,如果你请求 JSON 它会寻找 JSON,等等)

# app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def index
    @posts = Post.all
  end
end

现在,当您使用 header Accept: application/json 请求 /posts.json/posts 时,您的应用程序应该 return Jbuilder 构建的 JSON 响应.