【问题标题】:Rails - How get first record of associated table?Rails - 如何获取关联表的第一条记录?
【发布时间】:2020-04-16 19:54:40
【问题描述】:

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

我有postsimages 表。对于我的 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 }]

我需要将关联图像表中的第一张图像包含到我的 json 响应中..

提前致谢!

【问题讨论】:

    标签: ruby-on-rails ruby activerecord ruby-on-rails-5


    【解决方案1】:

    我建议使用序列化程序。 Active Model Serializer 非常标准且易于使用,但没有收到任何更新并且性能不佳。您可以选择任何其他序列化程序(我推荐 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
    

    【讨论】:

      【解决方案2】:

      您可以在调用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 文件,并选择与请求匹配的文件。 (如果您请求 HTML,它将查找 HTML 文件,如果您请求 JSON,它将查找 JSON,等等。)

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

      现在,当您使用标头 Accept: application/json 请求 /posts.json/posts 时,您的应用程序应该返回由 Jbuilder 构建的 JSON 响应。

      【讨论】:

        猜你喜欢
        • 2016-12-14
        • 1970-01-01
        • 1970-01-01
        • 2021-10-14
        • 1970-01-01
        • 2014-11-08
        • 1970-01-01
        • 1970-01-01
        • 2013-05-05
        相关资源
        最近更新 更多