如何在轨道上的ruby中引用控制器中的另一个类?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在轨道上的ruby中引用控制器中的另一个类?相关的知识,希望对你有一定的参考价值。

我试图在我的控制器内使用服务类。我无法弄清楚如何在rails中引用其他类。这是我的users_controller,位于app/controllers/api/v1下:

class Api::V1::UsersController < ApplicationController
  respond_to :json
  skip_before_filter :verify_authenticity_token
  before_filter :initialize_user_service

  def create
    @service.create
    render json: CustomResponse.new(
      {
        user: @service.user,
      }
    )
  end

  def initialize_user_service
    @service = Services::UserService.new(user_params)
  end

  def user_params
    params.permit(:email, :password, :password_confirmation, :first_name, :last_name)
  end
end

我试图引用位于users_service.rb的这个app/services/users_service.rb类:

class Services::UserService
  attr_reader :session, :user

  def initialize(params)
    # @user_id = params[:id]
    @params = params
  end

  def create
    user = User.create(@params)
    if user.save
      return user
    else
      false
    end
  end
end

但是我在控制台中收到以下错误:

NameError (uninitialized constant Api::V1::UsersController::Services):

有谁知道我可以做什么来访问这个类?我找不到解决方案。我想它可能与我的config/application.rb文件有关,但我不确定是什么。

答案

我想,问题在于您的文件名:app/services/users_service.rb。由于你的班级名称是UserService,它应该是:app/services/user_service.rbuser_service而不是users_service)。

UserService将在自动加载路径中从一个名为user_service.rb的文件中加载该类。

按以下方式定义您的服务: 文件名:app/services/user_service.rb。 定义:

module Services
  class UserService
    attr_reader :session, :user

    def initialize(params)
      # @user_id = params[:id]
      @params = params
    end

    def create
      user = User.create(@params)
      if user.save
        return user
      else
        false
      end
    end
  end
end

Services::UserService.new(user_params)应按预期工作。

另一答案

应该是::Services::UserService.new(user_params),Ruby假设您在Api :: V1模块中声明此类,::表示根模块。或者您可以像这样声明您的服务:

class Api::V1::Services::UserService end

另一答案

我认为这是因为定义的命名空间。只需将服务类直接放在服务目录中即可。检查ActiveSupport::Dependencies.autoload_paths以了解包含哪些文件夹的基本概念。即使您使用的是命名空间,也需要使用它来更新自动加载路径。类似下面的东西

config.autoload_paths += %W( #{config.root}/app/your_xyz_path )
另一答案

定义这样的服务就足够了。这不需要命名空间:

class UserService
end

# using
@service = UserService.new(user_params)
另一答案

app目录下的代码是自动加载的,也是所有目录。因此,您的服务类中应该没有命名空间。

class UserService
end

这应该适用于任何控制器或模型/类

user_service = UserService.new
另一答案

无需定义命名空间,只需使用您的服务名称编写它,如下所示

class UserService

  attr_reader :session, :user

  def initialize(params)
    # @user_id = params[:id]
    @params = params
  end

  def create
     user = User.create(@params)
       if user.save
            return user
       else
            false
       end
  end

end

并使用UserService.new(params)调用它并且对于生产模式在application.rb文件中定义它以自动加载服务,如下面的config.autoload_paths += Dir[Rails.root.join('app', 'services')]

以上是关于如何在轨道上的ruby中引用控制器中的另一个类?的主要内容,如果未能解决你的问题,请参考以下文章

编程语言“在轨道上”意味着啥?

试图在轨道上安装红宝石

无法在轨道上的可安装引擎中加载模型

在轨道上反应/反应国际

张贴在铁轨上的红宝石的另一页上

如何将类名作为变量传递给ruby中的另一个类