从ActiveRecord::Base继承的User类的父类不匹配



我试图找出我的超类不匹配错误。我读过的关于这个问题的所有帖子都把这个问题描述为User在我的应用程序中被两次定义为一个类。

在我的例子中,它没有定义两次。我有一个服务文件夹,其中有一个用户文件夹(用于用户服务类)。在该用户文件夹中,我有一个名为organization_mapper_service的文件。Rb, with:

class User < ActiveRecord::Base
      class OrganisationMapperService
        def self.call(user: u)
          new(user: user).call
        end
        def initialize(user: u)
          self.user = user
        end
        def call
          if matching_organisation.present?
            # user.organisation_request.new(organisation_id: matching_organisation.id)
            # user.update_attributes!(organisation_id: matching_organisation.id)
          else
            #SystemMailer.unmatched_organisation(user: user).deliver_now
          end
        end
        private
        attr_accessor :user
        def matching_organisation
          User::OrganisationMapperService.new(user).matching_organisation
        end
      end
    end

除此之外,我有我的用户模型,它将用户定义为:

class User < ApplicationRecord

我认为用我的方式定义服务类应该是好的,因为它继承了ActiveRecord::Base而不是ApplicationRecord。

有人能看出我在这里做错了什么吗?我还能在哪里找到用户的第二个定义呢?

接受SERGIO的建议

我将用户组织映射器服务更改为如下打开:

class User::OrganisationMapperService < ActiveRecord::Base

但是,然后给出了一个错误与我的用户::OrgRequestsController有新的定义如下:

def new
    @all_organisations    = Organisation.select(:title, :id).map { |org| [org.title, org.id] }
    @org_request = OrgRequest.new#form(OrganisationRequest::Create)
    matched_organisation = User::OrganisationMapperService.new(current_user).matching_organisation
    @org_request.organisation_id = matched_organisation.try(:id)
  end

错误信息然后说:

PG::UndefinedTable at /users/4/org_requests/new
ERROR:  relation "user_organisation_mapper_services" does not exist
LINE 8:                WHERE a.attrelid = '"user_organisation_mapper...

**接受塞尔吉奥的建议(完全)**

我将服务类改为:

class User::OrganisationMapperService 

然后我得到一个错误,说:

wrong number of arguments (given 1, expected 0)

这个错误突出显示了我的服务类的这一行:

def initialize(user: u)
      self.user = user
    end

我不知道该怎么做因为我显然有一个user如果继承了user

即使你解决了所有其他问题,你实际上还有一个无限递归在进行。

User::OrganisationMapperService.call(user: User.first)

相当于调用:

User::OrganisationMapperService.new(user: User.first).call

内部调用matching_organisation,所以有点相当于:

User::OrganisationMapperService.new(user: User.first).matching_organisation

同时,matching_organisation调用

User::OrganisationMapperService.new(user).matching_organisation

它会不停地转啊转。

它没有的唯一原因是因为wrong number of arguments (given 1, expected 0)错误。这是因为在matching_organisation方法中应该是User::OrganisationMapperService.new(user: user)而不是User::OrganisationMapperService.new(user)

回复评论的更新:

根据我的理解,User::OrganisationMapperService是一个服务类,它的工作是找到一些Organisation,然后执行某种工作。

User::OrganisationMapperService#matching_organisation方法实际上应该包含返回给定用户的匹配组织的代码。实现将完全取决于你如何构建你的数据库,但我将给出几个例子,让你走上正确的轨道或给你一些想法。

首先,organisations表可能有一个user_id列。在本例中,您可以对Organisation模型执行一个简单的查询,并使用用户的id执行搜索:

class User::OrganisationMapperService
  def matching_organisation
    # find the organisation and cache the result
    @matching_organisation ||= ::Organisation.where(user_id: user).first
  end
end

或者,您可能有某种连接表,其中可能在一个组织中有多个用户(仅在本例中,我们将此表称为"employments"):

class Employment < ApplicationRecord
  belongs_to :user
  belongs_to :organisation
end

我们可以在Organisation模型中添加作用域(这是必须要读的)来辅助查询:

class Organisation < ApplicationRecord
  has_many :employments
  has_many :users, through: :employments 
  scope :for_user, ->(user) {
    # return organisations belonging to this user
    joins(:users).merge( Employment.where(user_id: user) )
  }
end

最后,OrganisationMapperService#matching_organisation方法变成:

class User::OrganisationMapperService
  def matching_organisation
    # find the organisation and cache the result
    @matching_organisation ||= ::Organisation.for_user(user).first
  end
end

正在用两个单独的父类定义User类。别那样做。

应该是

class User::OrganisationMapperService

这样,您现有的User类将被加载和使用,而不是创建一个新的。

我认为用我的方式定义服务类应该是好的,因为它继承了ActiveRecord::Base而不是ApplicationRecord。

你的例子中的服务类不继承任何东西

最新更新