欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

firstOrNew firstOrCreate update create first or new create 可以使用 updateOrCreate 结合起来使用吧 自己亲自做的 有大用 有大大用

下面是自己亲自做的

$customer = Customer::firstOrCreate(['customer_tel'=>$customer_tel]);customer_tel必须是属于$fillable数组的
$customer->update($request->all());
先是 firstOrCreate 不要使用 firstOrNew ,表示己经创建了一个存在数据库里面的对象了,

然后 再
update (假如 firstOrNew ,很可能是新建一个并未存在于数据库的对象,就不能使用update了)



不能先使用 firstOrNew 再使用 updateOrCreate($request->all());因为updateOrCreate的第一个参数数组是不检查$fillable数组的
会把里面的全面填进去,所以 POST过来的 _token method 这些 参数值也会存进数据库,显然会出问题,


关于 updateOrCreate 可以看看 /node-admin/12931
下面是updateOrCreate的用法
// 如果没有匹配的模型则创建之 肯定可以 用法1)
$flight = App\Flight::updateOrCreate(    ['departure' => 'Oakland', 'destination' => 'San Diego'],    ['price' => 99] );

应该可以 用法2) 传两个数组,第二个数组是检查$fillable的
$profile = Profile::updateOrCreate( ['id' => $id], $request->all() );





How to use firstOrNew?

Hi,

Would you tell me whether I could use findOrNew or firstOrNew to replace the following cumbersome code?

public function store(Request $request)
{
    $test = Test::where('test_name', $request->test_name)
        ->first();
    if ($test == null) {
        $test = new Test($request->all());
        $test->save();
    } else {
        Test::where('id', $test->id)->update($request->all());
    }
}
       
thomaskim                    
Level 37                    
thomaskimNov 30, 2015                            


                   
RachidLaasri                    
Level 38                    
RachidLaasriNov 30, 2015                            

public function store(Request $request)
{ 
    $test = Test::firstOrNew('test_name', $request->test_name); 
    
    $test->update($request->all()); 
}
                   
               
bobbybouwmann                    
Level 50                    
bobbybouwmannNov 30, 2015                            


@RachidLaasri firstOrNew will not work, because it returns a new instance and now a new object!

You need to use firstOrCreate instead

public function store(Request $request) { 
    $test = Test::firstOrCreate('test_name', $request->test_name); 

    $test->update($request->all()); 
}
                       

The difference in the code below

    /**
     * Get the first record matching the attributes or create it.
     *
     * @param  array  $attributes
     * @return static
     */
    public static function firstOrCreate(array $attributes)
    {
        if (! is_null($instance = static::where($attributes)->first())) {
            return $instance;
        }

        // This returns a model object from the database
        return static::create($attributes);
    }

    /**
     * Get the first record matching the attributes or instantiate it.
     *
     * @param  array  $attributes
     * @return static
     */
    public static function firstOrNew(array $attributes)
    {
        if (! is_null($instance = static::where($attributes)->first())) {
            return $instance;
        }

        // This returns only an instance (new Test)
        return new static($attributes); 
    }
                   

                   

Level 50                    
bobbybouwmannNov 30, 2015                            


@thomaskim That should work too. However I find it in two lines more readable then in one line. So many ways to achieve one thing ;)

               
Maartencast                    
Level 1                    
MaartencastJul 28, 2017                        

Due to this post I was able to go from 3 lines to 2 lines saving my model, tnx!

@bobbybouwmann , what is your input on saving relationships and keeping it readable? Atm I have this function:

    public function storeOrUpdate( ContactRequest $request, $id )
    {
        $contact = Contact::firstOrCreate( ['id' => $id] );
        $contact->update( $request->all() );

        $address = Address::firstOrNew( ['contact_id' => $contact->id] );
        $address->fill( $request->input('address') );
        $contact->address()->save($address);

        return redirect()->route( 'contacts.index' );
    }
                       

In order to get the 'contact_id' set properly I had to save it this way, leaving me with 3 lines xD. I could also set the 'contact_id' manually, but this looks real stupid?

Also I ran into a situation where I had to save 3 models: $profile->person->address. At my current internship they use only separate functions store() & update(), I was wondering if I should just do this or create a nice looking single function like the one above.

using a single function, I can go with this in my form:

    route( 'contacts.storeOrUpdate', $contact->id ?? 0)
                       

and with this in my function:

$profile = Profile::updateOrCreate( ['id' => $id], $request->all() );

$person = Person::updateOrCreate( ['profile_id' => $profile->id], $request->input('person') );
$profile->person()->save($person);

$address = Address::updateOrCreate( ['person_id' => $person->id], $request->input('person.address') );
$person->address()->save($address);
                       

using separate functions, I need to check which route and method to use in the form, but I can go with easy function content:

//for the store function:
$profile = Profile::create( $input );
$person = $profile->person()->create( $input );
$person->address()->create( $input );

//for the update function:
$profile = Profile::withTrashed()->find($id);
$profile->fill( $input );
$profile->person->fill( $input );
$profile->person->address->fill( $input );
$profile->push();
                       

As a beginner, I can screw around for hours, not knowing what I should use and why xD.

来自  https://laracasts.com/discuss/channels/eloquent/how-to-use-firstornew?page=1

普通分类: