web-dev-qa-db-ja.com

未定義のメソッドIlluminate \ Database \ Query \ Builder :: associate()の呼び出し

リファレンス: 既存のEloquentリレーションシップをLaravel 4? で更新するにはどうすればよいですか?

_$userinfo = \Userinfo::find($id);
\User::find($id)->userinfo()->associate($userinfo)->save();
_

エラーが発生しています:Call to undefined method Illuminate\Database\Query\Builder::associate()

メソッド全体は次のとおりです。

_public function saveUser($id)
{
    $user = \User::find($id);

    $userdata = \Input::all();

    $rules = array(
        'email' => 'required|email',
        'state' => 'size:2',
        'Zip'   => 'size:5',
        'phone' => array('regex:/^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/')
    );

    $validator = \Validator::make($userdata, $rules);

    if ($validator->passes())
    {
        if ($userdata['email'] !== $user->email)
        {
            $rules = array('email' => 'unique:users');
            $validator = \Validator::make($userdata, $rules);
            if ($validator->fails()) return Redirect::route('admin.user.edit', array('user' => $user))
                ->with('error', 'Specified email already exists.');
        }

        $user->email                = $userdata['email'];
        $user->firstname            = $userdata['firstname'];
        $user->lastname             = $userdata['lastname'];

        $userinfoArray = array(
            'address'   => $userdata['address'],
            'city'      => $userdata['city'],
            'state'     => $userdata['state'],
            'Zip'       => $userdata['Zip'],
            'phone'     => preg_replace('/[^0-9]/', '', $userdata['phone'])
        );

        $user->save();

        if (!$user->userinfo)
        {
            $userinfo = new \Userinfo($userinfoArray);
            $userinfo = $user->userinfo()->save($userinfo);
        }
        else
        {
            $userinfo = \Userinfo::find($id);
            \User::find($id)->userinfo()->associate($userinfo)->save();
            //$user->userinfo()->update($userinfoArray);
        }

        return \Redirect::route('admin.user.detail', array('id' => $id))
            ->with('success', 'User updated.');
    }

    return \Redirect::route('admin.user.edit', array('id' => $id))
        ->withInput()
        ->withErrors($validator);
}
_
22
drack

associated()は、belongsTo関係のメソッドですが、上記からhasOne関係を介して呼び出そうとしているように見えます。

あなたは雄弁なモデルクラスコードを提供していないので、関係を正確に設定した方法がわかりませんが、持っている場合は推測しています:

class User extends Eloquent {
    public function userinfo()
    {
        return $this->hasOne('Userinfo');
    }
}

class Userinfo extends Eloquent {

    public function user() {
        return $this->belongsTo('User');
    }
}

次に、associateはUserInfoに対して呼び出される必要があります。これには、associate()メソッドが関連付けられているbelongsTo関係があるためです。

例えば

$user = \User::find(4);      
$userinfo = \UserInfo::find(1);

$userinfo->user()->associate($user);
$userinfo->save();

User_infoテーブルの外部キーuser_idを$ userオブジェクトのIDに設定します。

上記のコードを見ると、これが実際にやろうとしていることと、

$user->userinfo()->update($userinfoArray);

あなたがコメントアウトした呼び出しは、実際にあなたが達成しようとしているように見えることを行います。つまり、そのユーザーが既に存在する場合、現在のユーザーに関連するユーザー情報を更新します。

お役に立てれば。

グレン

32
glendaviesnz

hasOnebelongsToに変更します。次のようになります。

class User extends Eloquent {

    public function userinfo()
    {
        return $this->belongsTo('Userinfo');
    }
}

class Userinfo extends Eloquent {

    public function user() {
        return $this->belongsTo('User');
    }
}
3
Boston Kenne