質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.52%

laravel5.6にて、userがapplyボタンを押した際、companiesテーブルのidとusersテーブルのidをcompany_userという中間テーブルに挿入したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 939

chiicheer

score 9

 前提・実現したいこと

laravel5.6にて、applyボタンを押した際、companiesテーブルのidをcompany_idとしてまたusersテーブルのidをuser_idとして、company_userという中間テーブルの中に情報を飛ばしたい。どのページにどのコードを記載すれば、中間テーブルに情報をinsert出来るのかがわかりません。

 発生している問題・エラーメッセージ

        if ($request->method() == 'OPTIONS') {
            return (new Route('OPTIONS', $request->path(), function () use ($methods) {
                return new Response('', 200, ['Allow' => implode(',', $methods)]);
            }))->bind($request);
        }

        $this->methodNotAllowed($methods);
    }

    /**
     * Throw a method not allowed HTTP exception.
     *
     * @param  array  $others
     * @return void
     *
     * @throws \Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
     */
    protected function methodNotAllowed(array $others)
    {
        throw new MethodNotAllowedHttpException($others);
    }

    /**
     * Get routes from the collection by method.
     *
     * @param  string|null  $method
     * @return array
     */
    public function get($method = null)
    {
        return is_null($method) ? $this->getRoutes() : Arr::get($this->routes, $method, []);
    }

    /**
     * Determine if the route collection contains a given named route.
     *
     * @param  string  $name
     * @return bool
     */
    public function hasNamedRoute($name)
Arguments

エラーメッセージ
""

 該当のソースコード

↓コレがcompanies.showページのForm部分です。

{!!Form::open(['url'=>['/companies/{{$company->id}}'], 'method'=>'POST'])!!}

{{ csrf_field() }}
{{Form::hidden('company_id', '$company->id')}}
{{Form::hidden('user_id', 'Auth::user()->id')}}

{{Form::submit('apply',['class'=>'btn btn-danger'])}}

{!! Form::close() !!}

 試したこと

《companiesコントローラーページのstore部分に》

public function store(Request $request)
    {
        $company=Company::find($request->input('company_id'));
        $user=User::where('user_id', Auth::user()->id)->get();

        if($user && $company){
            $company->users()->attach($user->id);
        }
    }


を記載してみた。

《companyモデルの中↓》

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Company extends Model
{
    protected $fillable= array('country_id', 'title', 'description');

    public function country(){
        return $this->belongsTo('App\Country');
    }

    public function user()
    {
        return $this->belongsToMany('App\User')->using('App\Company_User');
    }


}

《userモデルページの中↓》

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password'
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    public function company (){
        return $this->belongsToMany('App\Company')->using('App\Company_User');
    }

}

また、$php artisan make:migration create_company_user_table
で中間テーブルを作成し、migrationファイルの中も

 public function up()
    {
        Schema::create('company_user', function (Blueprint $table){
            $table->increments('id');
            $table->integer('company_id')->unsigned();
            $table->foreign('company_id')->references('id')->on('companies');
            $table->integer('user_id')->unsigned();
            $table->foreign('user_id')->references('id')->on('users');
            $table->timestamps();
        });
    }


のように記載した後に、$php artisan migrate を行い正常にmigrateは出来ているのですが、
試しで$php artisan tinkerを使用して情報を中間テーブルにinsertしようとするとテーブルが見つからないというようなエラーが出ます。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

return $this->belongsToMany('App\User')->using('App\Company_User');
return $this->belongsToMany('App\Company')->using('App\Company_User');

これらの ->using() は不要です。
指定しないといけないのはモデルではなくテーブルです(命名規則に従えば書かなくてもいいですがその話は割愛します)。

https://readouble.com/laravel/5.6/ja/eloquent-relationships.html#many-to-many

return $this->belongsToMany('App\User', 'company_user');
return $this->belongsToMany('App\Company', 'company_user');

これで良いです。

https://readouble.com/laravel/5.6/ja/eloquent-relationships.html

モデルを結びつけている中間テーブルにレコードを挿入することにより、ユーザーに役割を持たせるにはattachメソッドを使います。

$user=User::where('user_id', Auth::user()->id)->get();

ここは find() を使わないとエラーが出ます。
where()->get() ではモデル型でなくコレクション型が返却されるからです。

if($user && $company){

個人的にはこの判定式は美しくないので findOrFail を使います。

https://readouble.com/laravel/5.6/ja/eloquent.html

モデルが見つからない時に、例外を投げたい場合もあります。これは特にルートやコントローラの中で便利です。findOrFailメソッドとクエリの最初の結果を取得するfirstOrFailメソッドは、該当するレコードが見つからない場合にIlluminate\Database\Eloquent\ModelNotFoundException例外を投げます。

Auth::user()->id も Auth::id() を使った方がスマートですね。

public function store(Request $request)
{
    $company=Company::findOrFail($request->input('company_id'));
    $user=User::findOrFail(Auth::id());

    $company->users()->attach($user->id);
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/09/03 14:00 編集

    https://github.com/dyoshikawa/teratail144162/pull/1/files

    直しました。
    私の環境で動作させる都合上companyテーブルのマイグレーションを変更したりしていますがその辺りは取り込まないで下さい。

    No Messageエラーについてはやはり
    {!!Form::open(['route' => 'companies.store'])!!}
    に変更することで直りましたので、この点再確認お願いします。

    applyボタンを押すことで中間テーブルへレコードが追加されることも確認済です。
    二回押してからtinkerで確認した結果が以下です。

    DB::table('company__users')->get()
    => Illuminate\Support\Collection {#2906
    all: [
    {#2903
    +"id": 1,
    +"company_id": 1,
    +"user_id": 1,
    +"created_at": null,
    +"updated_at": null,
    },
    {#2901
    +"id": 2,
    +"company_id": 1,
    +"user_id": 1,
    +"created_at": null,
    +"updated_at": null,
    },
    ],
    }

    キャンセル

  • 2018/09/03 14:55

    無事に動きました!!!!
    本当にありがとうございます。
    是非またご教授頂ければと思います。

    キャンセル

  • 2018/09/03 15:00

    はい、引き続き頑張って下さい。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • トップ
  • PHPに関する質問
  • laravel5.6にて、userがapplyボタンを押した際、companiesテーブルのidとusersテーブルのidをcompany_userという中間テーブルに挿入したい