类用户的超类不匹配-从ActiveRecord :: Base继承 [英] superclass mismatch for class User - inheriting from ActiveRecord::Base

查看:125
本文介绍了类用户的超类不匹配-从ActiveRecord :: Base继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试找出我的超类不匹配错误。我所读过的所有文章都将问题描述为用户在应用程序中两次被定义为类。

I am trying to figure out my superclass mismatch error. All the posts I've read about this describe the problem as being that User is defined twice as a class in my application.

对于我来说,它没有定义两次。我有一个服务文件夹,其中有一个用户文件夹(用于用户服务类)。在该用户文件夹中,我有一个名为Organisation_mapper_service.rb的文件,其中:

In my case, it isn't defined twice. I have a services folder and within that I have a user folder (for user service classes). In that user folder, I have a file called organisation_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

与此分开,我有我的用户模型,将用户定义为:

Separate to that, I have my user model which defines user as:

class User < ApplicationRecord

我认为以我的方式定义服务类应该没问题,因为它继承自ActiveRecord :: Base而不是ApplicationRecord。

I thought it should be fine to define the service class in the way I have because it inherits from ActiveRecord::Base rather than ApplicationRecord.

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

Can anyone see what I've done wrong here? Where else could I look for a second definition of User?

接受塞尔吉奥的建议

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

I change the user organisation mapper service to open as follows:

class User::OrganisationMapperService < ActiveRecord::Base

但是这给我的Users :: OrgRequestsController一个错误,其新定义为

But that then gives an error with my Users::OrgRequestsController which has new defined as follows:

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

the然后出现错误消息:

the error message then says:

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...

**接受SERGIO的建议(完全)**

**TAKING SERGIO'S SUGGESTION (exactly) **

我将服务等级更改为:

class User::OrganisationMapperService 

但随后出现一个错误,提示:

But then I get an error that says:

wrong number of arguments (given 1, expected 0)

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

That error highlights this line of my service class:

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

我不知道该怎么做,因为如果从用户那里继承下来,我显然拥有一个用户。

I don't know what to do about that because I clearly have a user if there is an inheritance from user.

推荐答案

即使您解决了所有其他问题,实际上仍然可以进行无限次递归。

Even once you solve all your other issues, you actually have an infinite recursion going on.

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

等同于调用:

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

内部调用 matching_organisation ,因此相当于:

Which internally calls matching_organisation, so is sort of equivalent to:

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

同时, matching_organisation 通话

User::OrganisationMapperService.new(user).matching_organisation

它会绕圈旋转。

唯一的原因不是因为个错误的参数数量(给定1,预期为0)错误。这是因为它应该是 User :: OrganisationMapperService.new(user:user)而不是 User :: OrganisationMapperService.new(user)在您的 matching_organisation 方法中。

The only reason it doesn't is because of the wrong number of arguments (given 1, expected 0) error. This is because it should be User::OrganisationMapperService.new(user: user) rather than User::OrganisationMapperService.new(user) in your matching_organisation method.

根据评论进行更新:

据我了解, User :: OrganisationMapperService 是一个服务类,用于查找一些组织,然后执行某种工作。

From what I understand, the User::OrganisationMapperService is a service class that does the job of finding some Organisation and then performing some sort of work.

User :: OrganisationMapperService#matching_organisation 方法实际上应包含返回给定用户的匹配组织的代码。实现将完全取决于您如何构造数据库,但是我将提供一些示例以使您走上正确的道路或提出想法。

The User::OrganisationMapperService#matching_organisation method should actually contain the code that returns the matching organisation for the given user. The implementation will completely depend on how you have structured your database, but I'll give a couple of examples to put you on the right track or give you ideas.

首先,您的 organizations 表可能具有 user_id 列。在这种情况下,您可以对组织模型进行简单的查询,然后使用用户的ID进行搜索:

First, Your organisations table may have a user_id column. In this case you could do a simple query on the Organisation model and perform a search using the user's id:

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

或者,您可能有某种加入表,其中一个组织可能有多个用户(仅在此示例中,我们将此表称为雇员):

Alternatively, you may have some sort of join table where there may be multiple Users at an Organisation (just for this example let us call this table 'employments'):

class Employment < ApplicationRecord
  belongs_to :user
  belongs_to :organisation
end

可以将范围(必须阅读)添加到组织模型来协助查询:

We can add scopes (this is a must read) to the Organisation model to assist with the query:

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

这篇关于类用户的超类不匹配-从ActiveRecord :: Base继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆