2016-11-20 3 views
-1

Rails 5の使い方を学びたいと思っていますが、特にサービスクラスの使い方を学びたいと思っています。Rails 5 - 組織のドメイン名に一致する電子メールアドレスを持つユーザーを見つけるためのサービスクラス

私は、ユーザーの指定した電子メールアドレス(ユーザーの属性:電子メール)を組織のドメイン名にマップするサービスクラスを作成しようとしています。組織にはemail_formatという属性があります。私はその属性を使用して、 "@"に続く電子メールアドレスの部分を保持します。

ユーザーがアカウントを作成するときに、私が使用する電子メールアドレスを使ってサインアップし、@の後ろのビットを私が知っている組織のそれぞれに一致させ、一致するものを探します。

私のこの試みは明らかに間違っていますが、私はその理由を理解するのに苦労しています。

私はUser、Organization、OrgRequestというリソースを持っています。団体は以下のとおりです。

class User::OrganisationMapperService #< ActiveRecord::Base 

    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 
     User::OrganisationMapperService.new(user: user) 
    end 

end 
:私はのようなサービスクラスを記述しようとしてい

ユーザー

belongs_to :organisation, optional: true 
has_one :org_request 

組織

has_many :org_requests 
has_many :users 

OrgRequest

belongs_to :user 
belongs_to :organisation 

私はこれに別のアプローチを把握することはできません

class Users::OrgRequestsController < ApplicationController 

    before_action  :authenticate_user!, except: [:new, :create, :requested] 
    before_action  :set_org_request, only: [:approved, :rejected, :removed] 

    # skip_before_action :redirect_for_unrequested_organisation 
    # skip_before_action :redirect_for_unknown_organisation 

    def index 
    organisation = Organisation.find_by(owner_id: current_user.id) 
    return redirect_to(user_path(current_user.id)) if organisation.nil? 

    @org_requests = organisation.org_requests 
    end 

    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 

    def create 
    @org_request = OrgRequest.new(org_request_params) 
    @org_request.user_id = current_user.id 

    if @org_request.save 
     OrgRequest::ProcessService.new(org_request).process 
     return redirect_to(user_path(current_user), 
     flash[:alert] => 'Your request is being processed.') 
    else 
     # Failure scenario below 
     @all_organisations = Organisation.select(:title, :id).map { |org| [org.title, org.id] } 

     render :new 
    end 
    end 

    def requested 
    # Need help - if this is contained in form inputs - how do i stop from overriding the submit path? 

    redirect_to(user_path(current_user)) 
    #not sure about this - a similar redirect isnt required for articles or project create 
    end 

    def approve 
    @org_request = current_user.organisation.org_requests.find(params[:id]) 

    if @org_request.state_machine.transition_to!(:approved) 
     flash[:notice] = "You've added this member." 
     redirect_to org_requests_path 
    else 
     flash[:error] = "You're not able to manage this organisation's members" 
     redirect_to :index 
    end 
    end 

    def remove 
    @org_request = current_user.organisation.org_requests.find(params[:id]) 

    if @org_request.state_machine.transition_to!(:removed) 
     flash[:notice] = "Removed from the organisation." 
     redirect_to action: :index 
     # format.html { redirect_to :index } 
     # format.json { render :show, status: :ok, location: @project } 
     # redirect_to action: :show, id: project_id 
     # add mailer to send message to article owner that article has been approved 
    else 
     flash[:error] = "You're not able to manage this organisation's members" 
     redirect_to(user_path(current_user)) 
     # redirect_to action: :show, id: project_id 
    end 
    end 

    def decline 
    @org_request = current_user.organisation.org_requests.find(params[:id]) 

    if @org_request.state_machine.transition_to!(:declined) 
     flash[:notice] = "You're not eligible to join this organisation" 
     redirect_to action: :index 
     # redirect_back(fallback_location: root_path) 
     # format.html { redirect_to :index } 
     # redirect_to action: :show, id: organisation_request.profile 
     # add mailer to send message to article owner that article has been approved 
    else 
     flash[:error] = "You're not able to manage this organisation's members" 
     redirect_to(user_path(current_user)) 
     # redirect_to action: :show, id: organisation_request.profile 
    end 
    end 

    private 
    # Use callbacks to share common setup or constraints between actions. 
    def set_org_request 
     @org_request = OrgRequest.find(params[:id]) 
     authorize @org_request 
    end 

    # Never trust parameters from the scary internet, only allow the white list through. 
    def org_request_params 
     params.require(:org_request).permit(:organisation_id, :name) # Need help - not sure if I need to put user id and organisation id in this permission 
    end 

end 

私はその後で組織要求コントローラを持っています。

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

が、私は以前ここに、この問題についての質問をしています:

wrong number of arguments (given 1, expected 0) 

エラーメッセージが私のサービスクラスの7行を強調、持っている:私はこれをしようとすると、私はこのエラーを取得するsuperclass mismatch for class User - inheriting from ActiveRecord::Base

しかし、私はアドバイスのドリフトや何が原因で起こっているのか把握していません。この試みは、私が少なくとも10の異なるチュートリアルから集めた提案をマッシュアップしたものです - それで、それは非常に正しいとは思えませんが、私はこの作業のさまざまな部分がどのように異なって試してみるかを理解するのに苦労しています。

誰でも私にこの試行の進め方を教えてもらえますか?

組織マッパーデコレータがあります

class User < ActiveRecord::Base 
    class OrganisationMapper < ::ApplicationDecorator 

    def matching_organisation 
     @matching_organisation ||= Organisation.by_email_format(email_format).first 
    end 

    def email_format 
     user.email.split('@').last 
    end 

    private 

    def user 
     @model 
    end 
    end 
end 

アプリケーションデコレータがあります

class ApplicationDecorator 
    def initialize(model) 
    @model = model 
    end 

    private 
    def method_missing(method, *args) 
    args.empty? ? @model.send(method) : @model.send(method, *args) 
    end 
end 

組織要求サービスクラスがあります

class OrgRequest::CreateService < ActiveRecord::Base 

    attr_accessor :org_request 

    def self.call(user_id: user_id, organisation_id: org_id) 
     new(user_id: user_id, organisation_id: organisation_id).call 
    end 

    def initialize(user_id: user_id, organisation_id: org_id) 
     self.user_id   = user_id 
     self.organisation_id = organisation_id 
    end 

    def call 
     self.org_request \ 
     = OrgRequest.new(user_id: current_user.id, 
            organisation_id: params[:org_request][:organisation_id]) 

     if org_request.save 
     # send the email 
     true 
     else 
     false 
     end 
    end 


end 

NEXT ATTEMPT

私が考えることのできるすべてのバリエーションを試しました。私が試していることは何も私には意味がありませんが、私が見つけることができる例は意味をなさない。

私のサービスクラスは、現在持っている:

class User::OrganisationMapperService #< ActiveRecord::Base 

    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.org_request.new(organisation_id: matching_organisation.id) 
     # if found create a request for that user to enter the organisation 
     if match_domain.present? 
      OrgRequest.create(user: @user, organisation_id: @organisation_domain.organisation.id) #if organisation 

     # 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 
    # User::OrganisationMapperService.new(user: user).Organisation.by_email_format(email_format).first 
    # end 

    # def matching_organisation 
    # @matching_organisation ||= Organisation.by_email_format(email_format).first 
    # end 

    def user_domain 
     user.email.split('@').last 
    end 

    def organisation_domain 
     @organisation = Organisation.find_by(email_format: user_domain) 
    end 

    # def user_email_domain 
    # # extract domain from users email 
    # user_email_domain = @user.email.split('@').last 
    # end 
    def match_domain 
     return unless @user_domain == @organisation.email_format 
    end 

    # find an organisation with a matching domain 
    # end 

end 

それははっきり間違っているのです。エラーメッセージは言う:

NameError - undefined local variable or method `organisation' for #<User::OrganisationMapperService:0x007faec6ec06b8> 

私が入れているので、いずれかのエラーメッセージの意味を理解することはできません「@」 '組織のすべてのインスタンスの前にちょうどそのエラーが離れて行くようにしようし。それはしません。

助けてください。

ANOTHER COMPLETELY無意味なエラーメッセージが私は別の電子メールドメインは、私のサービス・クラスで、組織の電子メールの形式と一致するかどうかをチェックするための方法を記述しようとしているに行きませんでした。

呼び出し方法は、今持っている:

def call 
     if user_domain == Organisation.email_format.any? 
      OrgRequest.create(user: @user, organisation_id: @organisation_domain.organisation.id) #if organisation 
     else 
     end 
    end 

コンソールにエラーメッセージは言う:email_format:私の組織テーブルは、それが呼ばれる内の属性を持っているので、持っている

NoMethodError - undefined method `email_format' for #<Class:0x007faec72d8ac0> 

はナンセンスであることを。コンソールでは、次のように書くことができます。

o = Organisation.first.email_format 
    Organisation Load (3.3ms) SELECT "organisations".* FROM "organisations" ORDER BY "organisations"."id" ASC LIMIT $1 [["LIMIT", 1]] 

これは私が探している結果をもたらします。

私はレールがどのように通信しているかを知るために(私の知恵の端まで)努力しています。私はそれの何らかの感覚を作ることはできません。呼び出し方法で行くの

次の試行

次の推測:

def call 
     if user_domain == organisation_domain? 
      OrgRequest.create(user: @user, organisation_id: @organisation_domain.organisation.id) #if organisation 

     else 
     end 

は、このエラーが発生します。

NoMethodError - undefined method `organisation_domain?' for #<User::OrganisationMapperService:0x007faec3be3600>: 

私は単一のフォームを見つけることができないようこのエラーを生成しない式の

+0

エラーは、OrganisationMapperServiceクラスにorganisation_domainがないと言っていますか?メソッド...それを追加します – alexanderkustov

+0

メソッドorganisaiton_domainはOrganisationMapperServiceで定義されています。エラーメッセージdoesntは私には意味をなさない。 – Mel

+0

私は持っています。 def organisation_domain @ organisation = Organisation.find_by(email_format:user_domain) end。私は冒頭に 'a'を追加して、エラーメッセージを表示させないようにしました。私はそこにすべきだとは思わない。 – Mel

答えて

0

私は、コードのメンターでセッションを持っていました。これが答えです。私はそれが学ぶことを試みている誰かを助けるかもしれないことを願っています。

class User::OrganisationMapperService #< ActiveRecord::Base 

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

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

    def call 
     if organisation_domain.present? 
      OrgRequest.create(user: @user, organisation_id: organisation_domain.id) #if organisation 

     else 
     end 
    end 

    private 

    attr_accessor :user 


    def user_domain 
     user.email.split('@').last 
    end 

    def organisation_domain 
     @organisation ||= Organisation.find_by(email_format: user_domain) 
    end 


end 
0

問題は次の行にあるように表示されます。

matched_organisation = User::OrganisationMapperService.new(current_user).matching_organisation 

ではなく、このようになります。

matched_organisation = User::OrganisationMapperService.new(user: current_user).matching_organisation 
+0

こんにちは@leandroico - これはありがたいですが、matched_organisationはこの20回の試行でコメントが外されていません。今のところ問題を解決しようとしています。 – Mel

関連する問題