お世話になっております。
railsのAPIモードについての質問です。
質問内容は、
ActionController::APIを継承したら、メソッドが継承できなくなった理由は何か?
です。
前提・実現したいこと
#####実現したいこと
ApplicationControllerの継承先をBaseからAPIに変更したい
#####前提
現在、nuxt.jsとruby on railsでSSRのアプリケーションを作成しております。
今までrailsをAPIとして使用しているにも関わらず、ApplicationControllerの継承先がActionController::Baseでした。
そこで、
動作をより軽くするためにBaseからAPIに継承先を変更したい
と思っております。
発生している問題・エラーメッセージ
エラーメッセージ
Completed 500 Internal Server Error in 474ms (ActiveRecord: 0.0ms | Allocations: 95322) NoMethodError (undefined method `user_check' for #<Api::SchedulesController:0x000055627c30c350>):
問題なく動いていた状態で、継承先をBaseからAPIに変更すると、上記のエラーが出ました。
該当のソースコード
ruby
1# application_controller.rb(変更後) 2 3class ApplicationController < ActionController::API 4 include DeviseTokenAuth::Concerns::SetUserByToken 5 skip_before_action :verify_authenticity_token, if: :devise_controller? 6# 省略 7 def response_unauthorized 8 render json: '認証に失敗しました', status: 401 9 end 10 11 def get_time 12 time = Time.zone.now 13 hour = time.hour 14 min = time.min 15 min < 30 ? hour : hour += 0.5 16 hour 17 end 18 19 def user_check(id, request) 20 user = User.find(id) 21 if user.isPublic 22 true 23 else 24 response_unauthorized unless check_token(user, request) 25 end 26 end 27# 省略 28 def check_token(user, request) 29 client = request.headers['client'] 30 token = request.headers['access-token'] 31 user&.valid_token?(token, client) 32 end 33 protected 34 def configure_permitted_parameters 35 devise_parameter_sanitizer.permit(:update, keys: [:name, :isPublic]) 36 end 37end
ruby
1# api/schedules_controller.rb 2 3class Api::SchedulesController < ApplicationController 4 before_action -> { user_check(params[:user_id], request) }, 5 only: [:index, :liked_index, :create] 6 def index 7 schedules = Schedule.where(user_id: params[:user_id]) 8 render json: schedules 9 end 10# 略 11end
ruby
1# config/application.rb 2 3require_relative 'boot' 4require "rails" 5# Pick the frameworks you want: 6require "active_model/railtie" 7require "active_job/railtie" 8require "active_record/railtie" 9require "active_storage/engine" 10require "action_controller/railtie" 11require "action_mailer/railtie" 12require "action_mailbox/engine" 13require "action_text/engine" 14require "action_view/railtie" 15require "action_cable/engine" 16# require "sprockets/railtie" 17# require "rails/test_unit/railtie" 18# Require the gems listed in Gemfile, including any gems 19# you've limited to :test, :development, or :production. 20Bundler.require(*Rails.groups) 21module App 22 class Application < Rails::Application 23 # Initialize configuration defaults for originally generated Rails version. 24 config.load_defaults 6.0 25 config.time_zone = 'Tokyo' 26 config.autoload_paths += %W(#{config.root}/lib/validator) 27 # Settings in config/environments/* take precedence over those specified here. 28 # Application configuration can go into files in config/initializers 29 # -- all .rb files in that directory are automatically loaded after loading 30 # the framework and any gems in your application. 31 # WARNING消すために。version6.1になればいらなくなる 32 ActiveSupport::Deprecation.silenced = true if Rails.version == '6.0.2.2' 33 # Only loads a smaller set of middleware suitable for API only apps. 34 # Middleware like session, flash, cookies can be added back manually. 35 # Skip views, helpers and assets when generating a new resource. 36 config.api_only = true 37 # 日本語化 38 config.i18n.default_locale = :ja 39 config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s] 40 end 41end
試したこと
- エラーが出たあと、APIからBaseに戻すと問題なく動作したため、APIに変えたことが原因なのは間違いありません。
- user_check以外のメソッドもundefinedで同じエラーが出ました。
- config/application.rbでconfig.api_only = true であることを確認。
consoleにて、以下を試しました。
a = ApplicationController.new # application_controllerのインスタンスを作成 a.get_time # インスタンスメソッドのget_timeを呼び出し
するとBaseから継承した場合、
[4] pry(main)> a = ApplicationController.new => #<ApplicationController:0x0000aaaaf7bdbcb0 @_action_has_layout=true, @_request=nil, @_response=nil, @_routes=nil, @rendered_format=nil> [5] pry(main)> a.get_time => 18
と、うまく動作するのに対して、APIから継承した場合、
[2] pry(main)> a = ApplicationController.new => #<ApplicationController:0x0000aaab16159110 @_request=nil, @_response=nil, @_routes=nil> [4] pry(main)> a.get_time NoMethodError: undefined method `get_time' for #<ApplicationController:0x0000aaab16159110>
となりました。
補足情報(FW/ツールのバージョンなど)
ruby (2.6.3) rails (6.0.2.2) devise (4.7.1) devise_token_auth (1.1.3)
お忙しいとは存じますが、よろしくお願い致します。
あなたの回答
tips
プレビュー