Dies ist das Ende der 18-teiligen Serialisierung.
Dieses Mal erstellen wir einen Benutzer-Controller. Es ist eine Zusammenstellung der Vergangenheit, daher empfehlen wir, dass Sie es versuchen, ohne den Beispielcode zu betrachten.
Es ist hauptsächlich für Administratoren zur Verwaltung von Benutzern und als Gruppe von Funktionen vorgesehen, mit denen Benutzer sich selbst aktualisieren und löschen können.
Ich werde mit dem Verfahren fortfahren.
$ rails g controller v1/users
Hier ist eine Gruppe von Dateien, die leicht modifiziert wurden, damit Rubocop nicht wütend wird.
app/controllers/v1/users_controller.rb
# frozen_string_literal: true
module V1
#
# users controller
#
class UsersController < ApplicationController
end
end
spec/requests/v1/users_request_spec.rb
# frozen_string_literal: true
require "rails_helper"
RSpec.describe "V1::Users", type: :request do
end
Drücken Sie den Befehl, um eine Datei zu erstellen.
$ rails g pundit:policy user
Nach geringfügigen Änderungen, damit Rubocop nicht wütend wird, ist es vorerst abgeschlossen.
app/policies/user_policy.rb
# frozen_string_literal: true
#
#Benutzerrichtlinienklasse
#
class UserPolicy < ApplicationPolicy
#
# scope
#
class Scope < Scope
def resolve
scope.all
end
end
end
spec/policies/user_policy_spec.rb
# frozen_string_literal: true
require "rails_helper"
RSpec.describe UserPolicy, type: :policy do
let(:user) { User.new }
subject { described_class }
permissions ".scope" do
pending "add some examples to (or delete) #{__FILE__}"
end
permissions :show? do
pending "add some examples to (or delete) #{__FILE__}"
end
permissions :create? do
pending "add some examples to (or delete) #{__FILE__}"
end
permissions :update? do
pending "add some examples to (or delete) #{__FILE__}"
end
permissions :destroy? do
pending "add some examples to (or delete) #{__FILE__}"
end
end
Überprüfung der Spezifikationen.
Hier ist die Implementierung in diesem Sinne.
spec/policies/user_policy_spec.rb
# frozen_string_literal: true
require "rails_helper"
RSpec.describe UserPolicy, type: :policy do
let(:user) { create(:user) }
let(:another_user) { create(:user) }
let(:admin_user) { create(:user, :admin) }
subject { described_class }
permissions :index?, :create?, :destroy? do
it "Nicht erlaubt, wenn nicht angemeldet" do
expect(subject).not_to permit(nil, user)
end
it "Nicht zulässig, wenn Sie als Benutzer ohne Administratorrechte angemeldet sind" do
expect(subject).not_to permit(user, user)
end
it "Erlaubt, wenn Sie als Administrator angemeldet sind" do
expect(subject).to permit(admin_user, user)
end
end
permissions :show?, :update? do
it "Nicht erlaubt, wenn nicht angemeldet" do
expect(subject).not_to permit(nil, user)
end
it "Nicht erlaubt, wenn angemeldet, aber ein anderer Benutzer" do
expect(subject).not_to permit(user, another_user)
end
it "Erlaubt, wenn Sie als Administrator angemeldet sind" do
expect(subject).to permit(admin_user, user)
end
it "Erlaubt, wenn angemeldet und derselbe Benutzer" do
expect(subject).to permit(user, user)
end
end
end
Der Punkt ist, dass ein anderer Benutzer namens "another_user" definiert ist. Zu diesem Zeitpunkt haben wir noch keine Richtlinie festgelegt. Stellen Sie daher sicher, dass einige Tests Moos sind.
app/policies/user_policy.rb
# frozen_string_literal: true
#
#Benutzerrichtlinienklasse
#
class UserPolicy < ApplicationPolicy
def index?
admin?
end
def show?
me? || admin?
end
def create?
admin?
end
def update?
me? || admin?
end
def destroy?
admin?
end
private
def me?
@record == @user
end
#
# scope
#
class Scope < Scope
def resolve
scope.all
end
end
end
Der Punkt ist, eine private Methode namens "me?" In user_policy.rb zu definieren.
Mine?
In application_policy.rb wurden @ record.user == @ user
und @ record
s user
mit dem eigenen verglichen.
Dieses Mal werden wir jedoch prüfen, ob "@ record" und "@ user" übereinstimmen, sodass die englische Grammatik "ich" anstelle von "meine" lautet. Außerdem scheint es, dass im Moment nur users_controller mit user
selbst verglichen werden kann, also habe ich es user_policy anstelle von application_policy vorgeschlagen.
Der Test sollte ohne besondere Erwähnung bestanden haben. </ div> </ details>
spec/requests/v1/users_request_spec.rb
# frozen_string_literal: true
require "rails_helper"
RSpec.describe "V1::Users", type: :request do
before do
@user = create(:user, name: "Benutzertest")
@authorized_headers = authorized_user_headers @user
admin = create(:user, :admin)
@authorized_admin_headers = authorized_user_headers admin
end
describe "GET /v1/users#index" do
before do
create_list(:user, 3)
end
it "Der normale Antwortcode wird zurückgegeben" do
get v1_users_url, headers: @authorized_admin_headers
expect(response.status).to eq 200
end
it "Die Nummer wird korrekt zurückgegeben" do
get v1_users_url, headers: @authorized_admin_headers
json = JSON.parse(response.body)
expect(json["users"].length).to eq(3 + 2) #Enthält 2 für Header
end
it "Die Antworten werden in absteigender Reihenfolge der ID zurückgegeben" do
get v1_users_url, headers: @authorized_admin_headers
json = JSON.parse(response.body)
first_id = json["users"][0]["id"]
expect(json["users"][1]["id"]).to eq(first_id - 1)
expect(json["users"][2]["id"]).to eq(first_id - 2)
expect(json["users"][3]["id"]).to eq(first_id - 3)
expect(json["users"][4]["id"]).to eq(first_id - 4)
end
end
describe "GET /v1/users#show" do
it "Der normale Antwortcode wird zurückgegeben" do
get v1_user_url({ id: @user.id }), headers: @authorized_headers
expect(response.status).to eq 200
end
it "Name wird korrekt zurückgegeben" do
get v1_user_url({ id: @user.id }), headers: @authorized_headers
json = JSON.parse(response.body)
expect(json["user"]["name"]).to eq("Benutzertest")
end
it "Die Antwort 404 wird zurückgegeben, wenn die ID nicht vorhanden ist" do
last_user = User.last
get v1_user_url({ id: last_user.id + 1 }), headers: @authorized_headers
expect(response.status).to eq 404
end
end
describe "POST /v1/users#create" do
let(:new_user) do
attributes_for(:user, name: "create_Namenstest", email: "[email protected]", admin: true)
end
it "Der normale Antwortcode wird zurückgegeben" do
post v1_users_url, params: new_user, headers: @authorized_admin_headers
expect(response.status).to eq 200
end
it "Ein weiterer Fall wird zurückgesandt" do
expect do
post v1_users_url, params: new_user, headers: @authorized_admin_headers
end.to change { User.count }.by(1)
end
it "name, email,admin kehrt korrekt zurück" do
post v1_users_url, params: new_user, headers: @authorized_admin_headers
json = JSON.parse(response.body)
expect(json["user"]["name"]).to eq("create_Namenstest")
expect(json["user"]["email"]).to eq("[email protected]")
expect(json["user"]["admin"]).to be true
end
it "Fehler werden zurückgegeben, wenn der Parameter ungültig ist" do
post v1_users_url, params: {}, headers: @authorized_admin_headers
json = JSON.parse(response.body)
expect(json.key?("errors")).to be true
end
end
describe "PUT /v1/users#update" do
let(:update_param) do
update_param = attributes_for(:user, name: "update_Namenstest", email: "[email protected]", admin: true)
update_param[:id] = @user.id
update_param
end
it "Der normale Antwortcode wird zurückgegeben" do
put v1_user_url({ id: update_param[:id] }), params: update_param, headers: @authorized_headers
expect(response.status).to eq 200
end
it "name, email,admin kehrt korrekt zurück" do
put v1_user_url({ id: update_param[:id] }), params: update_param, headers: @authorized_headers
json = JSON.parse(response.body)
expect(json["user"]["name"]).to eq("update_Namenstest")
expect(json["user"]["email"]).to eq("[email protected]")
expect(json["user"]["admin"]).to be false #Es ist ein Problem, wenn die Administratorberechtigung neu geschrieben werden kann. Lassen Sie sie daher als falsch
end
it "Fehler werden zurückgegeben, wenn der Parameter ungültig ist" do
put v1_user_url({ id: update_param[:id] }), params: { name: "" }, headers: @authorized_headers
json = JSON.parse(response.body)
expect(json.key?("errors")).to be true
end
it "Die Antwort 404 wird zurückgegeben, wenn die ID nicht vorhanden ist" do
last_user = User.last
put v1_user_url({ id: last_user.id + 1 }), params: update_param, headers: @authorized_admin_headers
expect(response.status).to eq 404
end
end
describe "DELETE /v1/users#destroy" do
it "Der normale Antwortcode wird zurückgegeben" do
delete v1_user_url({ id: @user.id }), headers: @authorized_admin_headers
expect(response.status).to eq 200
end
it "Eins weniger und kehrt zurück" do
expect do
delete v1_user_url({ id: @user.id }), headers: @authorized_admin_headers
end.to change { User.count }.by(-1)
end
it "Die Antwort 404 wird zurückgegeben, wenn die ID nicht vorhanden ist" do
last_user = User.last
delete v1_user_url({ id: last_user.id + 1 }), headers: @authorized_admin_headers
expect(response.status).to eq 404
end
end
end
Es gibt einige Überlegungen, die sich von denen der Post unterscheiden.
Ich baue ein.
Da die Antwort ein Administratorurteil enthält, muss der Serializer geändert werden.
app/serializers/user_serializer.rb
# user serializer
#
class UserSerializer < ActiveModel::Serializer
- attributes :id, :name, :email
+ attributes :id, :name, :email, :admin
end
Jetzt bist du bereit. Als nächstes werden wir die Controller-Implementierung eingeben. </ div> </ details>
Ändern Sie die Routen so, dass Sie auf den Controller zugreifen können.
config/routes.rb
Rails.application.routes.draw do
namespace "v1" do
resources :posts
+ resources :users
mount_devise_token_auth_for "User", at: "auth"
end
Als nächstes kommt der Controller. Dies kann fast von der Post abgelenkt werden.
app/controllers/v1/users_controller.rb
# frozen_string_literal: true
module V1
#
# users controller
#
class UsersController < ApplicationController
before_action :set_user, only: %i[show update destroy]
def index
users = User.order(created_at: :desc).limit(20)
authorize users
render json: users
end
def show
authorize @user
render json: @user
end
def create
user = User.new(user_create_params)
user[:provider] = :email
authorize user
if user.save
render json: user
else
render json: { errors: user.errors }
end
end
def update
authorize @user
if @user.update(user_params)
render json: @user
else
render json: { errors: @user.errors }
end
end
def destroy
authorize @user
@user.destroy
render json: @user
end
private
def set_user
@user = User.find(params[:id])
end
def user_create_params
#Zulassen, dass Administratorrechte nur beim Erstellen festgelegt werden
params.permit(:name, :email, :admin, :password)
end
def user_params
params.permit(:name, :email, :password)
end
end
end
Wie ich im Testabschnitt geschrieben habe, lässt der Administrator dies nur beim Erstellen zu. </ div> </ details>
das ist alles. Vielen Dank, dass Sie unsere Website 18 Mal besucht haben.
Erweitern Sie auf dieser Grundlage die Funktionen wie Kommentarfunktion und Social Login.
Recommended Posts