[RUBY] Erstellen Sie eine Bulletin-Board-API mit Autorisierung in Rails 6 # 12 Assoziation von Benutzer und Beitrag

Erstellen einer Bulletin Board-API mit Zertifizierungsberechtigung in Rails 6 # 11 Test und Validierung des Benutzermodells hinzugefügt

Vom Beitrag zum Benutzer verknüpfen

Beitrag und Benutzer zuordnen. Unter der Annahme, dass der beabsichtigte Leser das Rails-Tutorial abgeschlossen hat, werde ich die Erklärung der Bedeutung weglassen, aber fügen wir dem Artikel "Gehört zu: Benutzer" und "Hat: Viele: Beiträge" zum Benutzer hinzu.

$ rails g migration AddUserIdToPosts user:references

Wenn ein Datensatz vorhanden ist, wird er in der Nicht-Null-Einschränkung abgefangen, und die Migration führt zu einem Fehler. Daher wird db: reset durchgeführt (grob).

$ rails db:reset
$ rails db:migrate

app/models/post.rb


...
 class Post < ApplicationRecord
+  belongs_to :user
+
...

app/models/user.rb


...
   include DeviseTokenAuth::Concerns::User

 
+  has_many :posts, dependent: :destroy
+
...

Versuchen Sie nach dem Zuordnen der beiden Tabellen, "Rails c" zu verwenden, um festzustellen, ob dies funktioniert.

$ rails  c
[1] pry(main)> user = User.create!(name: "hoge", email: "[email protected]",  password: "password")
[2] pry(main)> post = Post.create!(subject: "test", body: "testtest", user: user)
[3] pry(main)> user.posts
  Post Load (0.3ms)  SELECT "posts".* FROM "posts" WHERE "posts"."user_id" = $1  [["user_id", 1]]
=> [#<Post:0x000000000488dbb0
  id: 1,
  subject: "test",
  body: "testtest",
  created_at: Tue, 08 Sep 2020 08:36:20 UTC +00:00,
  updated_at: Tue, 08 Sep 2020 08:36:20 UTC +00:00,
  user_id: 1>]
[4] pry(main)> post.user
=> #<User id: 1, provider: "email", uid: "[email protected]", name: "hoge", email: "[email protected]", created_at: "2020-09-08 08:36:11", updated_at: "2020-09-08 08:36:11">

Anscheinend können Sie sicher Beiträge von Benutzer und Benutzer von Beitrag anrufen.

Fix Post Serializer

Ich möchte die ID, den Namen und die E-Mail-Adresse des Benutzers von der Posts-API erhalten. Zu diesem Zeitpunkt sollten der Serializer und der Controller repariert sein. Zumindest muss der Serializer nur funktionieren. Beachten Sie jedoch, dass eine große Menge nutzlosen SQL-Codes, das als N + 1-Problem bezeichnet wird, fließt und die Leistung sinkt, wenn Sie den Controller nicht ändern.

app/serializers/post_serializer.rb


...
 class PostSerializer < ActiveModel::Serializer
   attributes :id, :subject, :body
+  belongs_to :user

Dadurch bleibt der Benutzer zusammen.

$ curl localhost:8080/v1/posts/1
{"post":{"id":1,"subject":"test","body":"testtest","user":{"id":1,"provider":"email","uid":"[email protected]","name":"hoge","email":"[email protected]","created_at":"2020-09-08T08:36:11.972Z","updated_at":"2020-09-08T08:36:11.972Z"}}}

Es ist gut, dass sie zusammenhalten, aber ich habe viele unnötige Informationen vom Benutzer. Es gibt keinen Serializer für den Benutzer, also fügen wir ihn hinzu.

Erstellen Sie einen Benutzerserialisierer

Der Serializer wird beim Erstellen des Modells automatisch generiert. Da das Modell jedoch mit devise_token_auth erstellt wurde, wird der Befehl manuell ausgeführt. Darüber hinaus funktioniert activeModelSerializer nicht für die Antwort json des Controllers, die automatisch von devise_token_auth generiert wird. Wenn Sie es aktivieren möchten, müssen Sie den Devise Controller überschreiben, aber dieses Mal werde ich es weglassen.

Aus dem Postmodell im zukünftigen Benutzer

$ rails g serializer user

app/serializers/user_serializer.rb


# frozen_string_literal: true

class UserSerializer < ActiveModel::Serializer
  attributes :id, :name, :email
end
$ curl localhost:8080/v1/posts/1
{"post":{"id":1,"subject":"test","body":"testtest","user":{"id":1,"name":"hoge","email":"[email protected]"}}}

Dies ist vorerst in Ordnung.

Umgang mit N + 1-Problemen

Jetzt erstellen wir mehrere Benutzer- / Post-Daten mit Rails c und klicken auf "curl localhost: 8080 / v1 / posts". Ich kann die Daten sicher abrufen, aber wenn ich zum Terminal gehe, wird mit "Rails s" gestartet ...

Started GET "/v1/posts" for 127.0.0.1 at 2020-09-08 08:48:08 +0000
Processing by V1::PostsController#index as */*
  Post Load (0.3ms)  SELECT "posts".* FROM "posts" ORDER BY "posts"."created_at" DESC LIMIT $1  [["LIMIT", 20]]
  ↳ app/controllers/v1/posts_controller.rb:12:in `index'
[active_model_serializers]   User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 3], ["LIMIT", 1]]
[active_model_serializers]   ↳ app/controllers/v1/posts_controller.rb:12:in `index'
[active_model_serializers]   CACHE User Load (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 3], ["LIMIT", 1]]
[active_model_serializers]   ↳ app/controllers/v1/posts_controller.rb:12:in `index'
[active_model_serializers]   CACHE User Load (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 3], ["LIMIT", 1]]
[active_model_serializers]   ↳ app/controllers/v1/posts_controller.rb:12:in `index'
[active_model_serializers]   User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 2], ["LIMIT", 1]]
...
[active_model_serializers]   ↳ app/controllers/v1/posts_controller.rb:12:in `index'
[active_model_serializers]   CACHE User Load (0.0ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
[active_model_serializers]   ↳ app/controllers/v1/posts_controller.rb:12:in `index'
[active_model_serializers] Rendered ActiveModel::Serializer::CollectionSerializer with ActiveModelSerializers::Adapter::Json (30.42ms)
Completed 200 OK in 34ms (Views: 32.5ms | ActiveRecord: 0.8ms | Allocations: 21448)

Obwohl weggelassen, fließt eine große Menge an SQL auf diese Weise. Dies ist das N + 1-Problem.

Da der mit dem Beitrag verknüpfte Benutzer jeweils einen Datensatz gefunden und abgerufen hat, fließt eine große Menge nutzloser SQL.

Dies ist in Ordnung, wenn Sie es zum Zeitpunkt der Veröffentlichung von "Post.all" einfügen.

app/controllers/v1/posts_controller.rb


     def index
-      posts = Post.order(created_at: :desc).limit(20)
+      posts = Post.includes(:user).order(created_at: :desc).limit(20)
       render json: posts
     end
Started GET "/v1/posts" for 127.0.0.1 at 2020-09-08 08:51:50 +0000
Processing by V1::PostsController#index as */*
  Post Load (0.2ms)  SELECT "posts".* FROM "posts" ORDER BY "posts"."created_at" DESC LIMIT $1  [["LIMIT", 20]]
  ↳ app/controllers/v1/posts_controller.rb:12:in `index'
  User Load (0.4ms)  SELECT "users".* FROM "users" WHERE "users"."id" IN ($1, $2, $3)  [["id", 3], ["id", 2], ["id", 1]]
  ↳ app/controllers/v1/posts_controller.rb:12:in `index'
[active_model_serializers] Rendered ActiveModel::Serializer::CollectionSerializer with ActiveModelSerializers::Adapter::Json (5.32ms)
Completed 200 OK in 41ms (Views: 32.7ms | ActiveRecord: 5.1ms | Allocations: 17394)

Es gibt jetzt zwei Benutzer und Beiträge, einen für jede Tabelle.

Vorerst scheint die Bewegung der Anwendung behoben worden zu sein, aber wenn Sie rspec in diesem Zustand verschieben, wird sie in der Tat großartig moosiert. Nächstes Mal werden wir rspec und seed überprüfen.

Fortsetzung

Erstellen einer Bulletin Board-API mit Zertifizierungsberechtigung in Rails 6 # 13 Erteilen des Authentifizierungsheaders [Zur Serialisierungstabelle]

Recommended Posts

Erstellen Sie eine Bulletin-Board-API mit Autorisierung in Rails 6 # 12 Assoziation von Benutzer und Beitrag
Erstellen Sie mit Rails 6 # 18 eine Bulletin-Board-API mit Zertifizierung und Autorisierung. ・ Implementierung des Endbenutzer-Controllers
Erstellen Sie eine Bulletin-Board-API mit Autorisierung in Rails 6 # 11. Benutzermodelltest und Validierung hinzugefügt
Erstellen Sie eine Bulletin-Board-API mit Zertifizierung und Autorisierung mit Rails 6 # 1 Environment Construction
Erstellen Sie eine Bulletin Board-API mit Zertifizierungsberechtigung in Rails 6 # 13 Grant-Authentifizierungsheader
# 4 nach Validierung und Testimplementierung zum Erstellen einer Bulletin Board-API mit Zertifizierung und Autorisierung in Rails 6
Erstellen Sie eine Bulletin Board-API mit Zertifizierung und Autorisierung mit Rails 6 # 3 RSpec. FactoryBot wird eingeführt und ein Post-Modell erstellt
Erstellen Sie eine Bulletin Board-API mit Zertifizierung und Autorisierung im Rails 6 # 5-Controller und leiten Sie die Implementierung weiter
Einführung von # 10 devise_token_auth zum Erstellen einer Bulletin Board-API mit Zertifizierung und Autorisierung in Rails 6
Erstellen Sie eine Bulletin Board-API mit Zertifizierung und Autorisierung in Rails 6 # 2 Einführung in Git und Rubocop
Einführung des Experten Nr. 15 zum Erstellen einer Bulletin-Board-API mit Zertifizierung und Autorisierung in Rails 6
Erstellen Sie eine Bulletin Board-API mit Zertifizierung und Autorisierung in Rails 6 # 17. Fügen Sie Administratorrechte hinzu
Erstellen Sie eine Bulletin Board-API mit Zertifizierung und Autorisierung in Rails 6 # 14 Seed. Anzeige der Ausführungszeit
# 16 Richtlinieneinstellung zum Erstellen einer Bulletin Board-API mit Zertifizierungsberechtigung in Rails 6
Einführung des Serializers Nr. 9 zum Erstellen einer Bulletin-Board-API mit Zertifizierung und Autorisierung in Rails 6
Erstellen Sie eine Bulletin Board-API mit Zertifizierung und Autorisierung in Rails 6 # 6. Zeigen Sie, erstellen Sie die Implementierung
Erstellen Sie eine Bulletin Board-API mit Zertifizierungsberechtigung im Rails 6 # 7-Update und zerstören Sie die Implementierung
[Rails] Erhalten Sie access_token zum Zeitpunkt der Twitter-Authentifizierung mit Sorcery und speichern Sie es in der Datenbank
Eine Notiz von dem, worauf ich gestoßen bin und was ich beim Aufholen von Laravel von Rails bemerkt habe
[Implementierungsverfahren] Erstellen Sie eine Benutzerauthentifizierungsfunktion mithilfe von Hexerei in Rails
Ich habe versucht, die Rails-API mit TDD von RSpec zu implementieren. Teil2 -Benutzerauthentifizierung-
Ich habe versucht, mit Rails eine Gruppenfunktion (Bulletin Board) zu erstellen
[Rails 6] Registrieren und Anmelden mit Devise + SNS-Authentifizierung (mehrere Links zulässig)
So erhalten Sie die ID eines Benutzers, der sich in Swift bei Firebase authentifiziert hat
Überprüfen Sie das ID-Token eines von AWS Cognito in Java authentifizierten Benutzers
Erstellen Sie mit Java + MySQL ein einfaches Bulletin Board
Versuchen Sie, ein Bulletin Board in Java zu erstellen
[Rails] Rangfolge und Paginierung in der Reihenfolge der Likes
[Rails] [Docker] Kopieren und Einfügen ist in Ordnung! So erstellen Sie eine Rails-Entwicklungsumgebung mit Docker