【问题标题】:Rails: Using service class methods in a scope queryRails:在范围查询中使用服务类方法
【发布时间】:2016-06-22 04:38:01
【问题描述】:

我有一个用户模型。

我正在尝试将我的用户索引视图设置为仅显示那些已完成入职流程的用户。

我的做法是:

索引:

<% Users.onboarded.each do |user| %>

在我的 user.rb 中,我尝试为入职定义一个范围,如下所示:

  scope :onboarded, -> { where (:user_is_matchable?) }

我的组织服务类中有一个方法:

class UserOrganisationMapperService

  attr_accessor :user
private

  def user_is_matchable?
    profile.present? && matching_organisation.present?

  end

当我尝试这个时,我收到一条错误消息:

undefined method `onboarded' for Users:Module

谁能看出我哪里出错了?

【问题讨论】:

  • 首先:UsersUser 在您的 user.rb 文件中.. 类的实际名称是什么?因为它应该是User 而不是Users
  • 您在user.rb 中定义了onboarded,但您在Users 模块上调用它。你应该打电话给User
  • 其次:scope :onboarded, -&gt; { where (:user_is_matchable?) } 这行不通。范围是一个 ActiveRecord 查询——它只能处理数据库中实际结构的细节。如果您的用户表中没有名为user_is_matchable?,则此范围将抱怨并且不起作用。

标签: ruby-on-rails methods scope


【解决方案1】:

首先:UsersUser 在您的 user.rb 文件中.. 类的实际名称是什么?因为它应该是User 而不是Users

其次:scope :onboarded, -&gt; { where (:user_is_matchable?) } 这是行不通的。范围是一个 ActiveRecord 查询——它只能处理数据库中实际结构的细节。如果您的用户表中没有名为user_is_matchable?,则此范围将抱怨并且不起作用。

您需要将该范围设置为仅适用于数据库的内容。

我只是在猜测(您没有在这里向我们提供您的关系的完整结构),但您是否能够执行以下操作:

scope :onboarded, -> { where ("profile_id IS NOT NULL AND matching_organisation_id IS NOT NULL") }

???

或者,您需要使其仅在 ruby​​ 中运行 - 这会更慢(特别是如果您的表变得非常大,因为用户表不会这样做)。但是,如果您对它的超慢速度感到满意,那么您可以这样做:

class User < ActiveRecord::Base
  def self.onboarded
    all.select(&:user_is_matchable?)
  end

或类似的东西......

【讨论】:

  • 嗨 - 是的,我可以使用这个想法。我的数据库中没有“匹配的组织 ID”。我有一种方法来检查是否有一个。相反,我可以使用这个想法,但我不知道如何在代码中编写它: scope :onboarded, -> { where ("user.profile_id IS NOT NULL AND user.profile.organisation_id IS NOT NULL") }
  • 我尝试了第二个建议(self.onboarded 的方法),但我收到此错误:未定义的方法 `user_is_matchable?'对于#
  • @Mel 那是因为user_is_matchable?是一个私有方法,把它移到private声明上面
  • @jamesw - 我尝试将其移至私有之上,但我收到与私有之下相同的错误消息。
  • 感谢两位的建议。我找到了使第一个建议起作用的方法。
猜你喜欢
  • 2013-10-07
  • 2013-09-26
  • 2021-07-02
  • 1970-01-01
  • 1970-01-01
  • 2012-09-28
  • 1970-01-01
  • 2012-02-18
  • 1970-01-01
相关资源
最近更新 更多