Storing a new Contact (polymorphic Business/Person)

Posted 3 years ago by jlmmns

Hi all,

When I store a new Contact, it can either be a Business or a Person (polymorphism). And a Person can belong to a Business.

I've got everything working, but my store() method is rather bulky now... How would I go about simplifying this code?

/**
 * Store a newly created resource in storage.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 */
public function store(Request $request)
{
    // Is the authenticated user allowed to store contacts?
    $this->authorize('store', Contact::class);

    // Get a new contact number
    $number = $this->newNumber();

    // All request input data
    $data = $request->all();

    // Parse date
    $data['date'] = Carbon::createFromFormat(
        trans('app/general.date_format'),
        $request->input('date')
    );

    // Start database transaction
    DB::beginTransaction();

    // New Contact
    $contact = new Contact($data);
    $contact->number = $number;
    $this->team->contacts()->save($contact);

    // If Contact is a Business
    if ($request->input('business_or_person') === 'business')
    {
        // New Business
        $business = new Business($data);
        $this->team->businesses()->save($business);
        $business->contact()->save($contact);
    }

    // If Contact is a Person
    elseif ($request->input('business_or_person') === 'person')
    {
        // Parse date_of_birth
        $data['date_of_birth'] = $request->input('date_of_birth', null);

        if ( ! is_null($data['date_of_birth']))
        {
            $data['date_of_birth'] = Carbon::createFromFormat(
                trans('app/general.date_format'),
                $data['date_of_birth']
            );
        }

        // If Person belongs to a Business
        if ($request->has('business_id') && validate($request->input('business_id'), 'integer'))
        {
            // If Business cannot be found
            if ( ! $this->team->businesses()->where('id', $request->input('business_id'))->exists())
            {
                // Rollback database transaction
                DB::rollBack();

                // Alert
                $alert = [
                    'type'     => 'error',
                    'message'  => trans('app/alert.contact.business_not_found'),
                    'duration' => 3000
                ];

                // If Ajax request
                if ($request->ajax())
                {
                    // JSON response
                    return response()->json($alert);
                }

                // Flash alert
                flashAlert($alert);

                // Redirect back
                return back();
            }
        }

        // New Person
        $person = new Person($data);
        $this->team->people()->save($person);
        $person->contact()->save($contact);
    }

    // Commit database transaction
    DB::commit();
    
    // Flash alert
    flashAlert([
        'type'     => 'success',
        'message'  => trans('app/alert.contact.stored'),
        'duration' => 3000
    ]);

    // If Ajax request
    if ($request->ajax())
    {
        // JSON response
        return response()->json([
            'status'   => 'ok',
            'redirect' => team_route('app.contacts.edit', [ $contact->number ])
        ]);
    }

    // Redirect to contact edit page
    return redirect_team_route('app.contacts.edit', [ $contact->number ]);
}

Update: I've simplified the following part:

// If Person belongs to a Business
if ($request->has('business_id') && validate($request->input('business_id'), 'integer'))
{
    // If Business does not exist
    if ( ! $this->checkIfBusinessExists($request->input('business_id')))
    {
        // Rollback database transaction
        DB::rollBack();

        // Alert if Business does not exist
        $this->alertIfBusinessDoesNotExist($request);
    }
}

Please sign in or create an account to participate in this conversation.

Reply to

Use Markdown with GitHub-flavored code blocks.