2017-02-13 11 views
1

Я пытаюсь узнать, как написать класс обслуживания в моем приложении rails 5.Rails 5: вызов класса сервиса - отношение сопоставления

Когда пользователь регистрируется с помощью устройства, я пытаюсь включить класс обслуживания, который создает модели, связанные с учетной записью пользователя, при создании учетной записи пользователя.

В мой контроллер регистраций завещать, у меня есть:

class Users::RegistrationsController < Devise::RegistrationsController 

    before_action :configure_permitted_parameters, if: :devise_controller? 


    def create 
    super do |user| 
     if user.persisted? 
     User::CompleteRegistration.call(user: user) 
     end 
    end 
    end 

    protected 



    def configure_permitted_parameters 
    devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name, :last_name, :email]) 
    devise_parameter_sanitizer.permit(:account_update, keys: [:first_name, :last_name, :email, ]) 
    end 


    private 

end 

В моем приложении/услуги/папки пользователя, у меня есть файл с именем: complete_registration.rb:

class User::CompleteRegistration #< ActiveRecord::Base 

    def self.call(user: u) 
     new(user: user).call 
    end 

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

    def call 
     Profile::SetupService.call(user: user) 
     Setting::SetupService.call(user: user) 
     User::OrganisationMapperService.new(user: user).call 
    end 

    # def join_an_organisation 
    # render "organisation_requests/new" 
    # end 

    private 

    attr_accessor :user 
end 

Когда я пытаюсь сохраните это, а затем зарегистрируйтесь как пользователь, я могу увидеть сообщение об ошибке:

NameError - uninitialized constant User::CompleteRegistrations: 

Отмечу, что это ха s pluralized слово «регистрация». Я не знаю, связано ли это с проблемой. Я попытался сохранить файл как множественное число и переименовал класс как множественное число, но это не сработало.

Фактическая ошибка визуализации говорит:

PG::UndefinedTable at /users 
ERROR: relation "complete_registration_services" does not exist 
LINE 8:    WHERE a.attrelid = '"complete_registration_se... 

Я не могу расширить сообщение, чтобы получить более подробную информацию, но нет никакого отношения можно найти, потому что оно не активную запись таблицы, которые я пытаюсь позвонить ,

Я также попытался добавить обратный вызов для моей модели пользователя в качестве альтернативного решения:

class User < ApplicationRecord 
    after_update :after_confirmation_setup 
def after_confirmation_setup 
    return unless !self.confirmed_at.blank? 
     User::CompleteRegistration.call(user: @user) 
    end 

Но это не работает либо.

Может ли кто-нибудь увидеть, как настроить приложение для вызова класса обслуживания при создании пользователя (из регистрационного контроллера или любого другого метода)?

ответ

1

По внешнему виду это похоже на проблему с именами.
С первых явлений (я не могу сказать однозначно, не используя вашу базу кода в консоли и отладку), но на основе быстрого сканирования и просмотра ошибок, которые вы получаете, это похоже на причуды Руби, которые я натолкнулся на несколько раз.

У вас есть класс пользователя в глобальной области действия (в вашем каталоге моделей), и у вас есть класс обслуживания User :: CompleteRegistration, который, когда вы вызываете откуда-то, вполне логично предположить, укажет на определенный пользователь :: Полный класс регистрации. Однако Ruby этого не видит.

User::CompleteRegistration можно разделить на две части, сначала оценивается пользователь :: Оценка, а Ruby выполняет поиск класса User и захватывает вашу модель. Затем он оценивает полную регистрацию и ищет определенную полную регистрацию, которая может использоваться в вашем классе пользователя. Возможно, именно поэтому вы получаете сообщение об ошибке. Он ищет отношения в пределах области модели пользователя.

По существу, когда вы пишете User::CompleteRegistration Ruby does not say Право! позволяет захватить класс User :: CompleteRegistration! Руби говорит Справа! позволяет захватить класс CompleteRegistration, который можно использовать в области пользователя!

Чтобы предотвратить это, я бы, возможно, изменил назначение вашего сервиса на нечто более простое, например: Registration::Complete и избегал совпадения имен классов/модулей в глобальной области.

также на стороне записки, я тоже люблю пользоваться услугами в коде, и я действительно не хочу писать бесстыдный плагин на SO, но, возможно, это ваш случай, это может помочь? Я написал gem to provide easy to use services, который имеет реализацию, не слишком отличающуюся от того, что вы используете, возможно, это может быть полезно, используете ли вы ее как драгоценный камень или просто просматриваете код в нем, я надеюсь, что-то, возможно, это поможет.

+0

Большое спасибо Джону. Это действительно полезно. Я определенно дам твою жемчужину попробовать. Еще раз спасибо. – Mel