У меня есть серверная часть Rails 5.2 только для api, использующая для аутентификации jwt, и я пытаюсь реализовать голосование с помощью гема act_as_votable. положительные голоса записываются, как и ожидалось, если я жестко закодировал переменную @current_user в действии контроллера. Однако при практическом использовании это не сработает.
вот мой authentic_controller.rb:
before_action :authorize_request, except: :login
# POST /auth/login
def login
@user = User.find_by_email(params[:email])
if @user&.authenticate(params[:password])
token = JsonWebToken.encode(user_id: @user.id)
time = Time.now + 24.hours.to_i
render json: { token: token, exp: time.strftime("%m-%d-%Y %H:%M"),
username: @user.username }, status: :ok
else
render json: { error: 'unauthorized' }, status: :unauthorized
end
end
private
def login_params
params.permit(:email, :password)
end
end```
my application_controller.rb:
```class ApplicationController < ActionController::API
def not_found
render json: { error: 'not_found' }
end
def authorize_request
header = request.headers['Authorization']
header = header.split(' ').last if header
begin
@decoded = JsonWebToken.decode(header)
@current_user = User.find(@decoded[:user_id])
rescue ActiveRecord::RecordNotFound => e
render json: { errors: e.message }, status: :unauthorized
rescue JWT::DecodeError => e
render json: { errors: e.message }, status: :unauthorized
end
end
private
end```
and my upvote method in the [model_name]_controller.rb:
```module Api
module V1
class ModelNamesController < ApplicationController
before_action :authorize_request, except: [:show, :index, :upvote, :downvote]
before_action :set_model_name, only: [:show, :update, :destroy, :upvote, :downvote]
...
def upvote
@decoded = JsonWebToken.decode(header)
@current_user = User.find(@decoded[:user_id])
@model_name.upvote_from @current_user
render layout: false
end
...
private
# Use callbacks to share common setup or constraints between actions.
def set_model_name
@model_name = ModelName.find(params[:id])
end
...
end
end```
routes.rb:
```Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :[model_name]s do
member do
put "upvote" => "[model_name]s#upvote"
put "downvote" => "[model_name]s#downvote"
end
end
end
end
root to: "[model_name]s#index"
resources :users, param: :_username
post '/auth/login', to: 'authentication#login'
end```
I am using Postman to do a PUT request to localhost/api/v1/[model_name]s/1/upvote. when @current user is set manually to User.find(1), votes are recorded.
However, logging in to Postman as User.find(3), i get no error
```I, [2019-05-27 10:53:06#64097] INFO -- : Started PUT "/api/v1/model_names/1/upvote" for ::1 at 2019-05-27 10:53:06 -0400
I, [2019-05-27 10:53:06#64097] INFO -- : Processing by Api::V1::ModelNamesController#upvote as */*
I, [2019-05-27 10:53:06#64097] INFO -- : Parameters: {"email"=>"user3@gmail.com", "password"=>"[FILTERED]", "id"=>"1", "model_name"=>{}}
D, [2019-05-27 10:53:06#64097] DEBUG -- : ModelName Load (0.6ms) SELECT "model_names".* FROM "model_names" WHERE "model_names"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
D, [2019-05-27 10:53:06#64097] DEBUG -- : ↳ app/controllers/api/v1/model_names_controller.rb:57
I, [2019-05-27 10:53:06#64097] INFO -- : Completed 200 OK in 60ms (Views: 0.1ms | ActiveRecord: 8.3ms)```
but votes are not recorded.