Rails: Using service class methods in a scope quer

2019-08-15 02:49发布

问题:

I have a user model.

I'm trying to set my user index view to show only those users who have completed an onboarding process.

My approach to doing that is:

index:

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

In my user.rb, I tried to define a scope, for onboarding, as:

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

I have a method in my organisation service class which has:

class UserOrganisationMapperService

  attr_accessor :user
private

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

  end

When i try this, I get an error that says:

undefined method `onboarded' for Users:Module

Can anyone see where I've gone wrong?

回答1:

Firstly: Users or User in your user.rb file.. what's the actual name of the class? because it should be User not Users

Secondly: scope :onboarded, -> { where (:user_is_matchable?) } this is just not going to work. a scope is an ActiveRecord query - it can only deal with details of the actual structure in the database. if you don't have a column in your users table called user_is_matchable? then this scope will complain and not work.

you need to make that scope into something that would work just on the database.

I'm only guessing (you haven't given us the full structure of your relations here) but would you be able to do something like:

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

???

Alternatively, you'll need to make it run just in ruby - which will be slower (especially if your table gets very big, as user-tables are wont to do). But if you're ok with it being super slow, then you could do this:

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

or something similar...