{"id":3851,"date":"2022-11-29T22:00:47","date_gmt":"2022-11-29T13:00:47","guid":{"rendered":"https:\/\/weseek.co.jp\/tech\/?p=3851"},"modified":"2023-04-17T10:38:13","modified_gmt":"2023-04-17T01:38:13","slug":"activemodelserializers%e3%81%a7sti%e3%81%aetype%e3%81%ab%e5%bf%9c%e3%81%98%e3%81%a6serializer%e3%82%92%e5%88%87%e3%82%8a%e6%9b%bf%e3%81%88%e3%82%8b","status":"publish","type":"post","link":"https:\/\/weseek.co.jp\/tech\/3851\/","title":{"rendered":"ActiveModel::Serializers\u3067STI\u306etype\u306b\u5fdc\u3058\u3066Serializer\u3092\u5207\u308a\u66ff\u3048\u308b"},"content":{"rendered":"<p>\u3053\u3093\u306b\u3061\u306f <a href=\"https:\/\/twitter.com\/Aqutam\">\u7530\u6751<\/a> \u3067\u3059\u3002<\/p>\n<p>STI \u3092\u4f7f\u7528\u3057\u3066\u8907\u6570\u306e type \u306e\u30e2\u30c7\u30eb\u30c7\u30fc\u30bf\u304c\u3042\u308a\u3001\u3053\u308c\u3092 1 \u3064\u306e API \u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u3067\u6df7\u305c\u3066\u8fd4\u3057\u305f\u3044\u3068\u3057\u307e\u3059\u3002<br \/>\n\u3053\u306e\u3068\u304d\u3001 STI \u306e type \u306b\u5fdc\u3058\u3066 serializer \u3092\u5207\u308a\u66ff\u3048\u305f\u304f\u306a\u308a\u307e\u3059\u3002<br \/>\n\u4eca\u56de\u306f\u3001\u305d\u306e\u65b9\u6cd5\u3092\u7d39\u4ecb\u3057\u307e\u3059\u3002<\/p>\n<p>STI \u306b\u3064\u3044\u3066\u306f<a href=\"https:\/\/railsguides.jp\/association_basics.html#%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%AB%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E7%B6%99%E6%89%BF-%EF%BC%88sti%EF%BC%89\">\u3053\u3061\u3089<\/a>\u3092\u53c2\u7167\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\n<p><!--more--><\/p>\n\n<h2>\u56f0\u3063\u305f\u3053\u3068<\/h2>\n<p>\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u30af\u30e9\u30b9\u968e\u5c64\u3092 STI \u3067\u5b9f\u73fe\u3057\u3066\u3044\u308b\u3068\u3057\u307e\u3059\u3002<\/p>\n<p><img src=\"https:\/\/weseek.co.jp\/tech\/wp-content\/uploads\/2022\/11\/post_erd-1.png\" alt=\"\" \/><\/p>\n<p>SimplePosts \u306f <code>title<\/code> \u3068 <code>body<\/code> \u3092\u3001 QAPosts \u306f <code>question<\/code> \u3068 <code>answer<\/code> \u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u3092\u6301\u3061\u307e\u3059\u3002 \u5171\u901a\u3057\u3066 <code>posted_at<\/code> \u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u3092\u6301\u3061\u307e\u3059\u3002<\/p>\n<p><code>\/api\/v1\/posts<\/code> \u3068\u3044\u3046 API \u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u3092\u5b9a\u7fa9\u3057\u3066\u3001\u4e0b\u8a18\u306e\u3088\u3046\u306a JSON \u3092\u8fd4\u3057\u305f\u3044\u3068\u3057\u307e\u3059\u3002<\/p>\n<pre><code class=\"language-json:\">{\n    &quot;posts&quot;: [\n        {\n            &quot;id&quot;: 3,\n            &quot;type&quot;: &quot;QAPost&quot;,\n            &quot;posted_at&quot;: &quot;2022-11-02T17:00:00.000Z&quot;,\n            &quot;question&quot;: &quot;\u8cea\u554f2&quot;,\n            &quot;answer&quot;: &quot;\u8cea\u554f2\u306e\u56de\u7b54\u3067\u3059\u3002&quot;\n        },\n        {\n            &quot;id&quot;: 4,\n            &quot;type&quot;: &quot;SimplePost&quot;,\n            &quot;posted_at&quot;: &quot;2022-11-02T15:00:00.000Z&quot;,\n            &quot;title&quot;: &quot;\u6295\u7a3f2&quot;,\n            &quot;body&quot;: &quot;Consectetur adipiscing elit.&quot;\n        },\n        {\n            &quot;id&quot;: 2,\n            &quot;type&quot;: &quot;QAPost&quot;,\n            &quot;posted_at&quot;: &quot;2022-11-01T16:00:00.000Z&quot;,\n            &quot;question&quot;: &quot;\u8cea\u554f1&quot;,\n            &quot;answer&quot;: &quot;\u8cea\u554f1\u306e\u56de\u7b54\u3067\u3059\u3002&quot;\n        },\n        {\n            &quot;id&quot;: 1,\n            &quot;type&quot;: &quot;SimplePost&quot;,\n            &quot;posted_at&quot;: &quot;2022-10-31T15:00:00.000Z&quot;,\n            &quot;title&quot;: &quot;\u6295\u7a3f1&quot;,\n            &quot;body&quot;: &quot;Lorem ipsum dolor sit amet.&quot;\n        }\n    ]\n}<\/code><\/pre>\n<p>Posts \u306e type \u304c <code>SimplePost<\/code> \u304b <code>QAPost<\/code> \u304b\u306b\u3088\u3063\u3066\u3001 JSON \u306e\u30ad\u30fc\u304c\u7570\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>JSON \u306e\u51fa\u529b\u3092 ActiveModel::Serializers \u3067\u884c\u3063\u3066\u3044\u308b\u5834\u5408\u3001  Posts \u306e type \u306b\u5fdc\u3058\u3066\u3001 Serializer \u3092\u5207\u308a\u66ff\u3048\u308b\u5fc5\u8981\u304c\u51fa\u3066\u304d\u307e\u3059\u3002<\/p>\n<h2>\u89e3\u6c7a\u65b9\u6cd5<\/h2>\n<p>\u5148\u306b\u30b3\u30fc\u30c9\u3092\u793a\u3057\u307e\u3059\u3002<\/p>\n<p>app\/serializers\/post_serializer.rb<\/p>\n<pre><code class=\"language-ruby:app\/serializers\/post_serializer.rb\">class PostSerializer &lt; ActiveModel::Serializer\n  attributes :id, :type, :posted_at\n\n  def attributes(requested_attrs = nil, reload = false)\n    @attributes = super(requested_attrs, reload)\n\n    case object\n    when SimplePost\n      @attributes.merge(SimplePostSerializer.new(object).attributes(nil, reload))\n    when QAPost\n      @attributes.merge(QAPostSerializer.new(object).attributes(nil, reload))\n    end\n  end\n\n  def json_key\n    &#039;posts&#039;\n  end\nend<\/code><\/pre>\n<p>app\/serializers\/simple_post_serializer.rb<\/p>\n<pre><code class=\"language-ruby:app\/serializers\/simple_post_serializer.rb\">class SimplePostSerializer &lt; ActiveModel::Serializer\n  attributes :title, :body\nend<\/code><\/pre>\n<p>app\/serializers\/qa_post_serializer.rb<\/p>\n<pre><code class=\"language-ruby:app\/serializers\/qa_post_serializer.rb\">class QAPostSerializer &lt; ActiveModel::Serializer\n  attributes :question, :answer\nend<\/code><\/pre>\n<p>app\/controllers\/api\/v1\/posts_controller.rb<\/p>\n<pre><code class=\"language-ruby:app\/controllers\/api\/v1\/posts_controller.rb\">module Api\n  module V1\n    class PostsController &lt; ApplicationController\n      def index\n        posts = Post.all.order(posted_at: :desc)\n\n        render json: posts, each_serializer: PostSerializer\n      end\n    end\n  end\nend<\/code><\/pre>\n<p>PostSerializer \u3067 <code>attributes<\/code> \u30e1\u30bd\u30c3\u30c9\u3092\u30aa\u30fc\u30d0\u30fc\u30e9\u30a4\u30c9\u3057\u307e\u3059\u3002\u5404\u30c7\u30fc\u30bf\u306f <code>object<\/code> \u3067\u53d6\u308c\u308b\u305f\u3081\u3001 case \u3067 class \u3092\u5224\u5b9a\u3057\u3001 <code>SimplePostSerializer.new(object).attributes(nil, reload)<\/code> \u3068 <code>QAPostSerializer.new(object).attributes(nil, reload)<\/code> \u3067\u3001 attributes \u3092\u751f\u6210\u3057 <code>@attributes<\/code> \u306b\u30de\u30fc\u30b8\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<p>\u53c2\u8003: <a href=\"https:\/\/github.com\/rails-api\/active_model_serializers\/blob\/0fbe0fad0dec9368e9335b6280a46ca13442727e\/lib\/active_model\/serializer.rb#L334-L343\">https:\/\/github.com\/rails-api\/active_model_serializers\/blob\/0fbe0fad0dec9368e9335b6280a46ca13442727e\/lib\/active_model\/serializer.rb#L334-L343<\/a><\/p>\n<p><code>json_key<\/code> \u30e1\u30bd\u30c3\u30c9\u3092\u30aa\u30fc\u30d0\u30fc\u30e9\u30a4\u30c9\u3057\u3066\u3044\u308b\u306e\u306f\u3001 json \u306e toplevel object \u3067 <code>posts<\/code> \u3068\u8868\u793a\u3055\u305b\u308b\u305f\u3081\u3067\u3059\u3002 \u3053\u308c\u3092\u5b9a\u7fa9\u3057\u306a\u3044\u3068\u3001\u4e0b\u8a18\u306e\u3088\u3046\u306b <code>qa_posts<\/code> \u3068\u3001\u6700\u521d\u306b Serializer \u3067\u51e6\u7406\u3057\u305f type \u304c key \u3068\u3057\u3066\u30bb\u30c3\u30c8\u3055\u308c\u3066\u3057\u307e\u3044\u307e\u3059\u3002<\/p>\n<pre><code class=\"language-json\">{\n    &quot;qa_posts&quot;: [\n        {\n            &quot;id&quot;: 3,\n            &quot;type&quot;: &quot;QAPost&quot;,\n            &quot;posted_at&quot;: &quot;2022-11-02T17:00:00.000Z&quot;,\n            &quot;question&quot;: &quot;\u8cea\u554f2&quot;,\n            &quot;answer&quot;: &quot;\u8cea\u554f2\u306e\u56de\u7b54\u3067\u3059\u3002&quot;\n        },\n        ...\n    ]\n}<\/code><\/pre>\n<p>\u306a\u304a\u3001 <code>jsonapi_include_toplevel_object<\/code> \u3092 <code>false<\/code> \u306b\u3057\u3066\u3044\u308b\u5834\u5408\u306f\u3001 <code>json_key<\/code> \u30e1\u30bd\u30c3\u30c9\u306e\u30aa\u30fc\u30d0\u30fc\u30e9\u30a4\u30c9\u306f\u4e0d\u8981\u3067\u3059\u3002<\/p>\n<p>\u53c2\u8003: <a href=\"https:\/\/github.com\/rails-api\/active_model_serializers\/blob\/0fbe0fad0dec9368e9335b6280a46ca13442727e\/lib\/active_model\/serializer.rb#L384-L392\">https:\/\/github.com\/rails-api\/active_model_serializers\/blob\/0fbe0fad0dec9368e9335b6280a46ca13442727e\/lib\/active_model\/serializer.rb#L384-L392<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u3053\u3093\u306b\u3061\u306f \u7530\u6751 \u3067\u3059\u3002 STI \u3092\u4f7f\u7528\u3057\u3066\u8907\u6570\u306e type \u306e\u30e2\u30c7\u30eb\u30c7\u30fc\u30bf\u304c\u3042\u308a\u3001\u3053\u308c\u3092 1 \u3064\u306e API \u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u3067\u6df7\u305c\u3066\u8fd4\u3057\u305f\u3044\u3068\u3057\u307e\u3059\u3002 \u3053\u306e\u3068\u304d\u3001 STI \u306e type \u306b\u5fdc\u3058\u3066 serializer \u3092<\/p>\n","protected":false},"author":2,"featured_media":3862,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[154],"tags":[],"_links":{"self":[{"href":"https:\/\/weseek.co.jp\/tech\/wp-json\/wp\/v2\/posts\/3851"}],"collection":[{"href":"https:\/\/weseek.co.jp\/tech\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/weseek.co.jp\/tech\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/weseek.co.jp\/tech\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/weseek.co.jp\/tech\/wp-json\/wp\/v2\/comments?post=3851"}],"version-history":[{"count":14,"href":"https:\/\/weseek.co.jp\/tech\/wp-json\/wp\/v2\/posts\/3851\/revisions"}],"predecessor-version":[{"id":3909,"href":"https:\/\/weseek.co.jp\/tech\/wp-json\/wp\/v2\/posts\/3851\/revisions\/3909"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/weseek.co.jp\/tech\/wp-json\/wp\/v2\/media\/3862"}],"wp:attachment":[{"href":"https:\/\/weseek.co.jp\/tech\/wp-json\/wp\/v2\/media?parent=3851"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/weseek.co.jp\/tech\/wp-json\/wp\/v2\/categories?post=3851"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/weseek.co.jp\/tech\/wp-json\/wp\/v2\/tags?post=3851"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}