基本的なイントロ


Railsを使用する場合、JSONオブジェクトを作成するのは簡単です.を使うindex or show メソッドは、利用可能なすべてのデータのリストを提供します.
#The Rails index method
def index
    render json: Book.all
end

#Returns this JSON hash
[
    {
        "id": 1
        "title": "Pride and Prejudice",
        "author": "Jane Austen",
        "description": "Set in England in the early 19th century, Pride and Prejudice tells the story of Mr and Mrs Bennet's five unmarried daughters after the rich and eligible Mr Bingley and his status-conscious friend, Mr Darcy, have moved into their neighbourhood. While Bingley takes an immediate liking to the eldest Bennet daughter, Jane, Darcy has difficulty adapting to local society and repeatedly clashes with the second-eldest Bennet daughter, Elizabeth.", 
        "image": "https://d1w7fb2mkkr3kw.cloudfront.net/assets/images/book/lrg/9781/4351/9781435159631.jpg", 
        "year": 1813,
        "genre": "Romance",
        "isbn": 9780140430721,
        "publisher": "T. Egerton, Whitehall",
        "length": 259,  
        "reading_time": 1, 
        "rating": 5,
        "created_at": "2022-04-14T15:42:23.682Z",
        "updated_at": "2022-04-14T15:42:23.682Z"
    }
]
それは多くの情報です!私はタイトル、著者、および評価を必要とするシナリオで何が起こりますか?私は常にすべての情報を渡すことができるだけ私が必要なものを使用します.それは働くことができる!もう一つのシナリオを働かせ続ける間、タイトル、イメージと評価だけが必要です.再び、私は全オブジェクトを通過することができて、必要なデータだけを使用することができます.しかし、それは多くの不必要な情報です.幸いにも、あなたが必要な情報だけを通過するレールの方法があります.使用.TONENE JSONは、特定の情報だけを渡すことができます.
#Adding to_json to the show method
def show
    books = Book.find(params[:id])
    render json: book.to_json(only:[:id, :title, :image, :rating])
end

#Will return the following:
[
    { 
        "id": 1,
        "title": "Pride and Prejudice",
        "image": "https://d1w7fb2mkkr3kw.cloudfront.net/assets/images/book/lrg/9781/4351/9781435159631.jpg",
        "rating": 5
    }
]
それははるかに効率的です!しかし、この方法はすぐに圧倒的で混雑することができます.我々が良いコーディング練習を観察して、懸念の分離をすることができる方法を望むならば、我々は異なる何かを見なければなりません.

シリアライザー


Active Model Serializers(AMS)は、JSONがどのようにレンダリングされるかをカスタマイズするためにプロジェクトに追加できます.それはあなたの懸念の分離を維持しながら正確なデータを取得する方法です.
起動するには、宝石をインストールする必要があります.gem 'active_model_serializers'

You can do this to on an active Rails project you are working on, just run bundle install after adding the gem, or add it during the setup portion, with all your gems.


インストール後、Railsジェネレータを使用してserializersを生成できます.rails g serializer bookこれにより、プロジェクトのアプリケーションフォルダーにSerializersフォルダーが生成されます.フォルダにはBookRank Serializerと呼ばれるファイルがあります.rb
class BookSerializer < ActiveModel::Serializer
  attributes :id
end
必要に応じて多くの属性を追加できます.上記の例では、ID、タイトル、イメージ、および評価だけを必要としています.
class BookSerializer < ActiveModel::Serializer
  attributes :id, :title, :image, :rating
end

#Will return the following:
[
    { 
        "id": 1,
        "title": "Pride and Prejudice",
        "image": "https://d1w7fb2mkkr3kw.cloudfront.net/assets/images/book/lrg/9781/4351/9781435159631.jpg",
        "rating": 5
    }
]
ファンタスティック!我々は、我々が必要なものを得ました、そして、良いコーディング慣行は懸念の分離で観察されます.
もう一度、すべてのステップ.
  • アクティブモデルシリーズ
  • シリアライザーを作成する
  • 必須属性の追加
  • カスタムメソッド
    また、シリアル化のカスタムメソッドを作成することもできます.
    class BookSummarySerializer < ActiveModel::Serializer
      attributes :id, :summary, :author
    
      def summary
        "#{self.object.title} - #{self.object.description[0..49]}..."
      end
    
    end
    
    サマリーと呼ばれるメソッドを作成し、その定義を定義します.この場合、本の説明のタイトルと最初の49文字を補間します.メソッドを作成した後、我々はちょうど属性のリストに追加し、それがJSONで表示されます.
    #Will return the following:
    [
        { 
            "id": 1,
            "summary": "Pride and Prejudice - Set in England in the early 19th century, Pride an...",
            "author": "Jane Austen"
        }
    ]
    
    それらのステップに再び行きましょう.
  • あなたのシリアライザーでカスタムメソッドを作成します
  • 新しいメソッドを属性に追加する
  • 必要に応じて多くのカスタムメソッドを追加することができますが、特定のポイントの後、我々は再び懸念の分離の問題に実行することができます.懸念を分離するには、カスタムシリアライザーを作成できます.
    カスタムシリリライザ
    上記のメソッドのカスタムシリアライザーを作成するには、シリアライザーを作成する必要があります.私たちは、私たちのserializersフォルダで物理的に新しいファイルを作成することができます、あるいは、我々は再びジェネレータを使うことができます.

    If you add a file by hand, make sure to observe proper syntax. Serializers need to be singular and named using snake_case. You will also need to add the class using PascalCase, and shovel it to your ActiveModel.
    class BookSummarySerializer < ActiveModel::Serializer


    BookRecruySerializerと呼ばれる新しいシリアライザーを作成または生成した後、カスタムメソッドを作成し、属性に追加する必要があります.
    class BookSummarySerializer < ActiveModel::Serializer
      attributes :id, :summary, :author
    end
    
    def summary
      "#{self.object.title} - #{self.object.description[0..49]}..."
    end
    
    #Will return the following:
    [
        { 
            "id": 1,
            "summary": "Pride and Prejudice - Set in England in the early 19th century, Pride an...",
            "author": "Jane Austen"
        }
    ]
    
    
    カスタムシリアライザーを完了したら、コントローラに追加する必要があります.Railsは自動的にコントローラと同じ名前のシリアライザーをチェックするので、カスタムシリアライザーを表示する場合は、JSONにレンダリングした後にコントローラに追加する必要があります.
    class BooksController < ApplicationController
        def index
            render json: Book.all
        end
    
        def show
            book = Book.find(params[:id])
            render json: book, serializer: BookSummarySerializer
        end
    end
    
    カスタムシリアライザーを作成する手順
  • カスタム名で新しいシリアライザーファイルを作成します
  • カスタムシリアライザーに必要な情報をすべて追加する
  • カスタムシリアライザーを適切なコントローラに追加する
  • 関連データ
    あなたのデータがモデルを通して作成された連想を持つならば、あなたは同様にあなたのserializersでそのデータにアクセスすることができます.私たちの本の例に基づいて、我々は多くのレビューを持つことができます協会を持つことができます.
    ブックレビュー
    あなたは、単に協会を追加することにより、serializersを通してあなたのJSONで表示される書籍の関連するレビューを見ることができます.

    If you have a many through relationship, you only need to write has_many for the info to show up.
    Ex: Author -< Books >- Genre
    An author has many books and has many genres through books. If you wanted to have the associated genres to your author on your JSON, you add the has_many :genres macro without needing to specify the "through" relationship.


    class BookSerializer < ActiveModel::Serializer
      attributes :id, :title, :author
    
      has_many :reviews
    end
    
    #Will return the following:
    [
        { 
            "id": 1,
            "title": "Pride and Prejudice",
            "author": "Jane Austen"
            "reviews": [
                { 
                    "name": "Bob"
                    "review": "Awesome classic!"
                },
                { 
                    "name": "Nancy"
                    "review": "Best book ever!"
                },
                { 
                    "name": "Lea"
                    "review": "Meh.. Not my speed."
                }
            ]
        }
    ]
    
    すごい!今私たちの本とすべての関連するレビューを持っている!
    それらのステップに再び行きましょう.
  • 関連付けをあなたのモデルで作成
  • 必要な関連付けをあなたのシリアライザーに追加する
  • 深くネストしたデータ
    別の例を見てみましょう.
    <書評>
    著者は多くのレビューを持っている多くの本があります.その情報が我々のJSONに現れることを望むならば、我々は同様にSerializersを通してそれをすることができましたか?アクティブモデル直列化は、我々のデータを過剰に複雑化するのを防ぐために1つのレベルを深く巣にするだけです.深いネストされたデータがまだ欲しかったら、AMSの振る舞いを上書きできます.
    我々は、我々のserializersを見ることから始めます.
    #Author Serializer
    class AuthourSerializer < ActiveModel::Serializer
      attributes :id, :first_name, :last_name
    
      has_many :books
    end
    
    
    #Book Serializer
    class BookSerializer < ActiveModel::Serializer
      attributes :id, :title
    
      belongs_to :author
      has_many :reviews
    end
    
    
    #Review Serializer
    class ReviewSerializer < ActiveModel::Serializer
        attributes :id, :name, :review
    end
    
    我々が上で見ることができるように、著者Serializerは本へのその関連を含みます、そして、本Serializerは著者とレビューにその協会を含みます.我々の深く入れ子になったモデルのために、適切なserializersに関連を含める必要があります.
    適切な関連付けを作成した後、我々はAMSの動作をオーバーライドできるように我々の著者のコントローラに情報を追加する必要があります.
    class AuthorController < ApplicationController
        def index
            render json: Book.all
        end
    
        def show
            author = Author.find(params[:id])
            render json: author, include: ['books', 'books.reviews']
        end
    end
    
    Showメソッドでは、JSONへのレンダリングのあと、Active Model Serializerに著者の情報を表示し、その作者に関連する書籍の情報を含めるように指示するコードがあります.また、それらの書籍に関連するレビューについても.さて、JSONは次のことを返します.
    [
        {
            "id": 1,
            "first_name": "Jane",
            "last_name": "Austen",
            "books": [
                {
                    "id": 1,
                    "title": "Pride and Prejudice",
                    "reviews": [
                        { 
                            "name": "Bob"
                            "review": "Awesome classic!"
                        },
                        { 
                            "name": "Nancy"
                            "review": "Best book ever!"
                        },
                        { 
                            "name": "Lea"
                            "review": "Meh.. Not my speed."
                        }
                    ]
                }
            ]
        }
    ]
    
    任務完了!
    もう一度一歩を踏み出そう.
  • シリアライザー
  • 適切なserializersに関連付けを追加する
  • 関連するコントローラでレンダリングする情報を含める
  • 最後の思考


    serializersは非常に強力で便利です.我々は彼らと多くを行うことができますし、正確にどのように我々はそれが必要な私たちのJSONを取得します.私たちが心に留めておくべき1つの点は、しかし、シリアライズ、カスタムシリアル化、およびカスタムメソッドのそれぞれで、我々はプログラムに複雑さを加えているということです.すべてのマクロとメソッドをすばやく追加し、物事を非常に複雑にすることができます.
    ソース
    Cover Image
    Flatiron
    Serializer Docs