質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

Devise

Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

2回答

2249閲覧

Rails API + React + devise current_api_v1_user.id nil:NilClass

aaa11

総合スコア14

React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

Devise

Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

1グッド

0クリップ

投稿2021/07/01 08:53

編集2021/07/08 03:15

#実現したいこと
Rails API + React + deviseでUserを登録しています。current_api_v1_user.idをTestテーブルに登録したいのですがNoMethodError (undefined method `id' for nil:NilClass):が出てしまいuser_idが登録できません。アドバイスいただけないでしょうか。

#エラー文

Started POST "/api/v1/tests" Processing by Api::V1::TestsController#create as HTML Parameters: {"title"=>"test", "image"=>"", "body"=>"test", "test"=>{"title"=>"test", "image"=>"", "body"=>"test"}} Completed 500 Internal Server Error in 1ms (ActiveRecord: 0.0ms | Allocations: 660) NoMethodError (undefined method `id' for nil:NilClass):

#gemファイル

gem 'devise' gem 'devise_token_auth' gem 'rack-cors'

#Userモデル
db/migrate/devise_token_auth_create_users.rb

class DeviseTokenAuthCreateUsers < ActiveRecord::Migration[6.1] def change create_table(:users) do |t| ## Required t.string :provider, :null => false, :default => "email" t.string :uid, :null => false, :default => "" ## Database authenticatable t.string :encrypted_password, :null => false, :default => "" ## Recoverable t.string :reset_password_token t.datetime :reset_password_sent_at t.boolean :allow_password_change, :default => false ## Rememberable t.datetime :remember_created_at ## Confirmable t.string :confirmation_token t.datetime :confirmed_at t.datetime :confirmation_sent_at t.string :unconfirmed_email # Only if using reconfirmable ## Lockable # t.integer :failed_attempts, :default => 0, :null => false # Only if lock strategy is :failed_attempts # t.string :unlock_token # Only if unlock strategy is :email or :both # t.datetime :locked_at ## User Info t.string :name t.string :nickname t.string :image t.string :email t.text :profile ## Tokens t.text :tokens t.timestamps end add_index :users, :email, unique: true add_index :users, [:uid, :provider], unique: true add_index :users, :reset_password_token, unique: true add_index :users, :confirmation_token, unique: true # add_index :users, :unlock_token, unique: true end end

#Testモデル
db/migrate/create_tests.rb

class CreateTests < ActiveRecord::Migration[6.1] def change create_table :tests do |t| t.integer :user_id t.string :title t.string :image t.text :body t.timestamps end end end

#app/models/user.rb

class User < ActiveRecord::Base devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable include DeviseTokenAuth::Concerns::User has_many :tests, dependent: :destroy end

#app/models/test.rb

class Test < ApplicationRecord belongs_to :user end

#app/controllers/application_controller.rb

rails

1class ApplicationController < ActionController::Base 2 include DeviseTokenAuth::Concerns::SetUserByToken 3 4 skip_before_action :verify_authenticity_token 5 helper_method :current_user, :user_signed_in? 6 7end

#Rails(TestsController)
controllers/api/v1/tests_controller.rb

rails

1class Api::V1::TestsController < ApplicationController 2 def create 3 @test = Test.new(test_params) 4 @test.user_id = current_api_v1_user.id 5 if @test.save 6 render json: { status: 200, data: test } 7 else 8 render json: { status: 500, message: "テストの作成に失敗しました" } 9 end 10 end 11 12 private 13 def test_params 14 params.require(:test).permit(:title, :image, :body) 15 end 16end

#SessionsController
controllers/api/v1/auth/sessions_controller.rb

class Api::V1::Auth::SessionsController < ApplicationController def index if current_api_v1_user render json: { is_login: true, data: current_api_v1_user } else render json: { is_login: false, message: "ユーザーが存在しません" } end end end

#routes.rb

Rails.application.routes.draw do namespace :api do namespace :v1 do resources :tests, only: %i[index show new create edit ] mount_devise_token_auth_for 'User', at: 'auth', controllers: { registrations: 'api/v1/auth/registrations' } namespace :auth do resources :sessions, only: %i[index] end end end end

#reactからSessionsControllerを叩いたjsonのデータ
イメージ説明

sho_a5👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

current_api_v1_userがちゃんと作られていないのではないでしょうか。undefined method `id' for nil:NilClassとなった場合、大抵

〇〇.id

の〇〇に問題があります。その辺りを重点的に見ていくと解決するのではないかと思います。

投稿2021/07/07 08:27

yaha4967

総合スコア106

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aaa11

2021/07/08 03:03

回答ありがとうございます。SessionsController、routes.rb、reactからSessionsControllerを叩いたjsonのデータを追加しました。SessionsControllerを叩いたcurrent_api_v1_userに中身が入っていることは確認できていますがTestsControllerで呼び出した際current_api_v1_userに中身が入っていないという事ですか?
yaha4967

2021/07/08 03:31

そう思います。 createアクションが問題の箇所ですよね? そこで puts "中身あるか#{current_api_v1_user}" みたいな事をすると確かめられると思います。
aaa11

2021/07/08 04:23

中身は何も表示されなかったのでやはりcurrent_api_v1_userに問題がありそうです。 @active_user = User.find_by(id: session[:user_id]) みたいな感じで定義しても中身がありませんでした。
yaha4967

2021/07/08 05:01

やっぱりそうですよね。 ここらからは私、deviceを使ったことないので分からないですけどもう一つ気になった点があってnamespaceが気になりました。的外れかもしれませんが。
aaa11

2021/07/08 06:05

controllers/api/v1/tests_controller.rbの場合/の部分がnamespaceにあたります。 憶測ですがgem の'devise_token_auth'とroutes.rbの表記方法が原因でcurrent_api_v1_userが空になっているかもしれません。
yaha4967

2021/07/08 11:28

routes.rbをちょっと読んでみて、これも憶測なのですが mount_devise_token_auth_for 'User', at: 'auth', controllers: { registrations: 'api/v1/auth/registrations' } これってマウント足りてなくないですか?
aaa11

2021/07/09 03:46

無事に解決しました。 React側が原因でcurrent_api_v1_userの中身がなかったみたいです。 色々時間を割いていただきありがとうございました。
guest

0

自己解決

current_api_v1_userに中身が入っていなかったのはReact側の実装が原因でした。

#変更前
src/lib/api/test.ts

react

1 2import client from "lib/api/client" 3import Cookies from "js-cookie" 4 5import { CreateTestParams } from "interfaces/index" 6 7export const createTest = (params: CreateTestParams) => { 8 return client.post("/tests", params)

#↓

#変更後
src/lib/api/test.ts

react

1 2import client from "lib/api/client" 3import Cookies from "js-cookie" 4 5import { CreateTestParams } from "interfaces/index" 6 7export const createTest = (params: CreateTestParams) => { 8 return client.post("/tests", params, { headers: { 9 "access-token": Cookies.get("_access_token"), 10 "client": Cookies.get("_client"), 11 "uid": Cookies.get("_uid") 12 }}) 13}

#tests_controller.rb

rails

1 2 def create 3 @test = Test.new(test_params) 4 5 if @test.save 6 render json: { status: 200, data: @test } 7 else 8 render json: { status: 500, message: "テストの作成に失敗しました" } 9 end 10 end 11 12 private 13 def test_params 14 params.require(:test).permit(:title, :image, :body).merge(user_id: current_api_v1_user.id) 15 end

headers情報を送ってないので中身が無いわけです。

投稿2021/07/09 03:45

aaa11

総合スコア14

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問