类的超类不匹配用户 - 从ActiveRecord :: Base继承

时间:2016-10-24 21:42:33

标签: ruby-on-rails ruby inheritance activerecord superclass

我想弄清楚我的超类错配错误。我读过的所有帖子都描述了这个问题,即User在我的应用程序中被定义为两次。

就我而言,它没有定义两次。我有一个服务文件夹,其中有一个用户文件夹(用于用户服务类)。在该用户文件夹中,我有一个名为organisation_mapper_service.rb的文件,其中包含:

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。

谁能看到我在这里做错了什么?我还能在哪里寻找用户的第二个定义?

采取塞尔吉奥的建议

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

class User::OrganisationMapperService < ActiveRecord::Base

但是那会给我的Users :: 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

我不知道该怎么做,因为如果有来自用户的继承,我显然有一个用户。

2 个答案:

答案 0 :(得分:2)

即使你解决了所有其他问题,你实际上也会进行无限递归。

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)错误。这是因为User::OrganisationMapperService.new(user: user)方法中应该User::OrganisationMapperService.new(user)而不是matching_organisation

更新以回复评论:

根据我的理解,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

或者,您可能会有某种联盟表,其中组织中可能有多个用户(仅为此示例,我们称之为此表&#39;就业&#39;):

class Employment < ApplicationRecord
  belongs_to :user
  belongs_to :organisation
end

我们可以将scopes (this is a must read)添加到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

答案 1 :(得分:0)

定义User类,有两个独立的父类。别这么做。

应该是

class User::OrganisationMapperService

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

  

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

示例中的服务类不会从任何内容继承。