2017-02-13 8 views
1

私のレール5アプリでサービスクラスを書く方法を学びたいと思っています。Rails 5:サービスクラス - リレーションマッピングの呼び出し

ユーザーがdeviseに登録すると、ユーザーアカウントの作成時にユーザーアカウントに関連付けられたモデルを作成するサービスクラスを組み込もうとしています。私の工夫登録コントローラで

、私が持っている:私はしようとすると

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 

:complete_registration.rb:私のアプリ/サービス/ユーザーフォルダに

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 

を、私はと呼ばれるファイルを持っていますヘクタール

NameError - uninitialized constant User::CompleteRegistrations: 

私はそれに注意:これを保存し、ユーザーとしてサインアップ、私が言うエラーメッセージを見ることができます「登録」という言葉が複数形になっています。これに問題があるかどうかは分かりません。私は複数のファイルを保存しようとし、クラスを複数の名前に変更しようとしましたが、うまくいきませんでした。

レンダリングされた実際のエラーは言う:

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 

しかし、それdoesntの仕事のどちらか。

ユーザー登録時にサービスクラスを呼び出すようにアプリケーションを設定する方法は誰にも分かりますか?

答えて

1

これは名前の問題のように見えます。
最初の外観(コンソールとデバッグでコードベースを実際に使用していないとはっきりと言うことはできません)から、速いスキャンに基づいて、これを受け取っているエラーを見てみると、これはRubyの癖の1つです何回か。

あなたはグローバルスコープ(modelsディレクトリ内)にUserクラスを持ち、User :: CompleteRegistrationというサービスクラスを持っています。どこからでも呼び出すと、完全に論理的で、定義されたUser ::完全な登録クラス。しかし、Rubyではそのようには見えません。

User::CompleteRegistrationは、最初にUser ::が評価され、RubyがUserクラスを検索してモデルを取得します。 CompleteRegistrationを評価し、Userクラスで使用できる定義済みのCompleteRegistrationを探します。これは、あなたが関係についての誤りを得ている理由かもしれません。 Userモデルスコープ内のリレーションを検索しています。

本質的に、あなたが書くときUser::CompleteRegistrationルビーdoesntは言う右! User :: CompleteRegistrationクラスを手に入れることができます!ルビーはと言っています。 Userスコープ内で使用できるCompleteRegistrationクラスを取得できます!

これを防ぐには、サービスの名前をRegistration::Completeのように単純なものに変更し、グローバルスコープ内でクラス/モジュール名が重複しないようにします。

また、私はコード内でサービスを使用するのが大好きです。私は本当に恥知らずなプラグインを書いていませんが、おそらくあなたのケースに役立つでしょうか?私はgem to provide easy to use servicesを書いていますが、あなたが使用しているものとあまり似ていない実装を持っています。おそらく、それを宝石として使うのか、単にそのコードをスキャンするのかにかかわらず、おそらく役に立つかもしれません。

+0

ありがとうジョン。これは本当に役に立ちます。私は間違いなくあなたの宝石にも試してみましょう。再度、感謝します。 – Mel

関連する問題