लारवेल एलोकेंट बनाना और अपडेट करना


165

नया रिकॉर्ड डालने या अपडेट करने के लिए शॉर्टहैंड मौजूद है या नहीं?

<?php

$shopOwner = ShopMeta::where('shopId', '=', $theID)
    ->where('metadataKey', '=', 2001)->first();

if ($shopOwner == null) {
    // Insert new record into database
} else {
    // Update the existing record
}

मैं अनुमान लगा रहा हूँ कि shopIdआपकी प्राथमिक कुंजी सही नहीं है?
सेरगुई पाराशिव

@ शेरगिरीपाराशिव, येप। यह नहीं है
1myb

@ErikTheDeveloper से उत्तर देखें। यह एक अच्छा एंबेडेड एलोकेंट विधि दिखाता है जो काम करना चाहिए।
cw24

इसी बात का पूरी तरह से जवाब नीचे दिए गए लिंक में दिया गया है stackoverflow.com/questions/18839941/…
Bashirpour

जवाबों:


232

यहाँ "lu cip" के बारे में एक पूर्ण उदाहरण दिया गया है:

$user = User::firstOrNew(array('name' => Input::get('name')));
$user->foo = Input::get('foo');
$user->save();

नीचे डॉक्स का अद्यतन लिंक दिया गया है जो कि लारवेल के नवीनतम संस्करण पर है

डॉक्स यहां: अपडेटेड लिंक


1
बिल्कुल सही! 'firstOrNew' भी 4.0 में मौजूद है (डॉक्स में उल्लेख नहीं किया गया है)
younes0

2
अगर हम ($ उपयोगकर्ता- मौजूद है) का उपयोग करके हम $ उपयोगकर्ता को नए / पुनः प्राप्त कर सकते हैं की जाँच कर सकते हैं।
Ryu_hayabusa

1
@Ryu_hayabusa कि दौड़ की स्थिति का कारण होगा
क्रिस हैरिसन

नया वाक्यविन्यास अद्यतन होने लगता है। InInsert (सरणी $ विशेषताएँ, सरणी $ मान = []] 5.5 में: github.com/laravel/framework/blob/5.5/src/Illuminate/Database-…
user1204214

86

अपडेट किया गया: 27 अगस्त 2014 - [ updateOrCreateकोर में निर्मित ...]

बस मामले में लोग अभी भी इस पार आ रहे हैं ... मुझे यह लिखने के कुछ हफ्तों बाद पता चला, कि यह वास्तव में लारवेल के एलोकेंट की कोर का हिस्सा है ...

एलोकेंट के समकक्ष विधि (एस) में खुदाई। आप यहाँ देख सकते हैं:

https://github.com/laravel/framework/blob/4.2/src/Illuminate/Database/Eloquent/Model.php#L553

पर: 570 और: 553

    /**
     * Create or update a record matching the attributes, and fill it with values.
     *
     * @param  array  $attributes
     * @param  array  $values
     * @return static
     */
    public static function updateOrCreate(array $attributes, array $values = array())
    {
        $instance = static::firstOrNew($attributes);

        $instance->fill($values)->save();

        return $instance;
    }

नीचे पुराना उत्तर


मुझे आश्चर्य हो रहा है कि क्या L4 कार्यक्षमता में किसी भी तरह से ऐसा करने के लिए बनाया गया है:

$row = DB::table('table')->where('id', '=', $id)->first();
// Fancy field => data assignments here
$row->save();

मैंने इस विधि को कुछ हफ्ते पहले बनाया था ...

// Within a Model extends Eloquent
public static function createOrUpdate($formatted_array) {
    $row = Model::find($formatted_array['id']);
    if ($row === null) {
        Model::create($formatted_array);
        Session::flash('footer_message', "CREATED");
    } else {
        $row->update($formatted_array);
        Session::flash('footer_message', "EXISITING");
    }
    $affected_row = Model::find($formatted_array['id']);
    return $affected_row;
}

मुझे आशा है कि वह मदद करेंगे। अगर कोई किसी को साझा करना चाहता है, तो मैं इसका एक विकल्प देखना पसंद करूंगा। @erikthedev_


वहाँ है और इसे firstOrNew / firstsOrCreate कहा जाता है
malhal

@malcolmhall मैंने उपरोक्त उत्तर अपडेट किया है। यह पता चलता है कि एलोक्वेंट में कई विशेषताएं हैं जो मैंने खुद को पुनर्निर्माण करते हुए पाया है;) डॉक्स ब्राउज़ करने में कुछ समय बिताने के लिए हमेशा अच्छा होता है :)
एरिक अयबर

packagist की 4.2.0 (स्थिर 2014/6/1) में अपडेट नहीं है। लेकिन कोई इसे स्रोत को देखते हुए लागू कर सकता है। ModelName::firstOrNew(['param' => 'condition'])->fill(Input::get())->save();करना चाहिए।
बिबस्थ

3
बस यह देखें कि लारवेल इसे लेन-देन के रूप में नहीं चलाता है, इसलिए यदि आपके पास अद्वितीय कुंजी है और एक अन्य उपयोगकर्ता इसे उसी कुंजी के साथ बनाता है तो एक साथ आपको अपवाद मिल सकता है। मेरा मानना ​​है कि RedBeanPHP के फायदों में से एक यह है कि आपके लिए एक लेन-देन में इस तरह का काम किया जाता है।
मल्हल

भरने के उपयोग को इंगित करने के लिए धन्यवाद () जिसने मुझे बहुत सहायता प्रदान की है!
सायप्रस

70

2020 अद्यतन

जैसा कि लारवेल में = = 5.3 , अगर कोई अभी भी उत्सुक है कि आसान तरीके से ऐसा कैसे किया जाए। इसका उपयोग करके संभव है:updateOrCreate() :।

उदाहरण के लिए पूछे गए प्रश्न के लिए आप कुछ का उपयोग कर सकते हैं:

$matchThese = ['shopId'=>$theID,'metadataKey'=>2001];
ShopMeta::updateOrCreate($matchThese,['shopOwner'=>'New One']);

ऊपर कोड ShopMeta द्वारा प्रतिनिधित्व की गई तालिका की जांच करेगा, जो shop_metasतब तक सबसे अधिक संभावना होगी जब तक कि स्वयं मॉडल में अन्यथा परिभाषित न हो

और इसके साथ प्रविष्टि खोजने का प्रयास करेंगे

स्तंभ shopId = $theID

तथा

स्तंभ metadateKey = 2001

और अगर यह मिल जाता है तो यह shopOwnerपाया गया पंक्ति के कॉलम को अपडेट कर देगा New One

यदि यह एक से अधिक मिलान पंक्तियों को पाता है तो यह पहली पंक्ति को अपडेट करेगा जिसका अर्थ है कि सबसे कम प्राथमिक id

यदि बिल्कुल नहीं मिला तो इसके साथ एक नई पंक्ति डालेंगे:

shopId = $theID, metadateKey = 2001औरshopOwner = New One

सूचना के लिए अपने मॉडल की जांच करें $fillableऔर मुकदमा करें कि आपके पास हर स्तंभ का नाम वहां परिभाषित है जिसे आप सम्मिलित करना चाहते हैं या अपडेट करना चाहते हैं और बाकी कॉलमों का या तो मान है या इसके मूल्यid कॉलम ऑटो ।

अन्यथा यह उदाहरण के ऊपर निष्पादित करते समय त्रुटि फेंक देगा:

Illuminate\Database\QueryException with message 'SQLSTATE[HY000]: General error: 1364 Field '...' doesn't have a default value (SQL: insert into `...` (`...`,.., `updated_at`, `created_at`) values (...,.., xxxx-xx-xx xx:xx:xx, xxxx-xx-xx xx:xx:xx))'

जैसा कि कुछ क्षेत्र होगा जिसमें नई पंक्ति सम्मिलित करते समय मूल्य की आवश्यकता होगी और यह संभव नहीं होगा क्योंकि इसके परिभाषित नहीं किया जाएगा $fillable या इसमें डिफ़ॉल्ट मान नहीं है।

अधिक संदर्भ के लिए कृपया यहां लारवेल डॉक्यूमेंटेशन देखें: https://laravel.com/docs/5.3/eloquent

वहाँ से एक उदाहरण है:

// If there's a flight from Oakland to San Diego, set the price to $99.
// If no matching model exists, create one.
$flight = App\Flight::updateOrCreate(
    ['departure' => 'Oakland', 'destination' => 'San Diego'],
    ['price' => 99]
);

जो बहुत कुछ साफ करता है।

क्वेरी बिल्डर अद्यतन

किसी ने पूछा है कि क्या लारवेल में क्वेरी बिल्डर का उपयोग करना संभव है। यहाँ Laravel डॉक्स से क्वेरी बिल्डर का संदर्भ दिया गया है।

क्वेरी बिल्डर बिल्कुल एलोकेंट के समान काम करता है इसलिए जो कुछ भी एलोकेंट के लिए सही है वह क्वेरी बिल्डर के लिए भी सही है। तो इस विशिष्ट मामले के लिए, बस अपने क्वेरी बिल्डर के साथ समान फ़ंक्शन का उपयोग करें:

$matchThese = array('shopId'=>$theID,'metadataKey'=>2001);
DB::table('shop_metas')::updateOrCreate($matchThese,['shopOwner'=>'New One']);

बेशक, डीबी मुखौटा जोड़ने के लिए मत भूलना:

use Illuminate\Support\Facades\DB;

या

use DB;

मुझे उम्मीद है यह मदद करेगा


क्वेरी बिल्डर के बारे में कैसे?
स्काई

इसके बारे में क्या है ? :)
शिक्षार्थी २०'१

मैं क्वेरी बिल्डर के साथ यही काम करना चाहता हूं। वाक्पटु नहीं। क्या यह संभव है?
आकाश

मेरे उत्तर को अपडेट करें, उपरोक्त उत्तर में "क्वेरी बिल्डर अपडेट" अनुभाग देखें।
लर्नर

मैंने DB :: table ('shop_metas') :: updateOrCreate मेथड की कोशिश की, लेकिन इससे मुझे मैक्रोएबल में खराब मेथोडकॉल अपवाद का पता चला। हालांकि मैं डीबी का उपयोग करता हूं;
स्वप्निल शेंडे

17

फ़ंक्शन सहेजें:

$shopOwner->save()

पहले से ही आप क्या चाहते हैं ...

लारावेल कोड:

    // If the model already exists in the database we can just update our record
    // that is already in this database using the current IDs in this "where"
    // clause to only update this model. Otherwise, we'll just insert them.
    if ($this->exists)
    {
        $saved = $this->performUpdate($query);
    }

    // If the model is brand new, we'll insert it into our database and set the
    // ID attribute on the model to the value of the newly inserted row's ID
    // which is typically an auto-increment value managed by the database.
    else
    {
        $saved = $this->performInsert($query);
    }

6
यह एक परमाणु अपवर्तक ऑपरेशन की तरह नहीं दिखता है। यदि ऐसा नहीं है, तो यह दौड़ की स्थिति पैदा कर सकता है।
एमिल विक्रोत्म

यह कोड यह जांचने के लिए है कि क्या मॉडल डीबी से लोड किया गया है या मेमोरी बेस्ड मॉडल है। अद्यतित होने के लिए कुंजी स्तंभों की स्पष्ट परिभाषा बनाएं या अपडेट करें और अंतर्निहित रूप से प्रदर्शन नहीं किया जा सकता है।
एएमआईबी

17

firstOrNewमौजूद नहीं होने पर रिकॉर्ड बनाएंगे और यदि पहले से मौजूद हैं तो एक पंक्ति को अपडेट करेंगे। आप updateOrCreateयहां भी उपयोग कर सकते हैं इसका पूरा उदाहरण है

$flight = App\Flight::updateOrCreate(
    ['departure' => 'Oakland', 'destination' => 'San Diego'],
    ['price' => 99]
); 

यदि ओकलैंड से सैन डिएगो के लिए एक उड़ान है, तो कीमत 99 डॉलर निर्धारित करें। यदि मौजूद नहीं है तो नई पंक्ति बनाएं

यहाँ संदर्भ संदर्भ: ( https://laravel.com/docs/5.5/eloquent )


7

यदि आपको DBलारवेल में उसी कार्यक्षमता का उपयोग करना है , जिसका >= 5.5आप उपयोग कर सकते हैं:

DB::table('table_name')->updateOrInsert($attributes, $values);

या शॉर्टहैंड संस्करण कब $attributesऔर $valuesसमान हैं:

DB::table('table_name')->updateOrInsert($values);

6
$shopOwner = ShopMeta::firstOrNew(array('shopId' => $theID,'metadataKey' => 2001));

फिर अपने बदलाव करें और बचत करें। ध्यान दें कि फ़र्स्टऑवरन इंसर्ट नहीं करता है अगर इसके नहीं पाए जाते हैं, अगर आपको ज़रूरत है तो इसके फ़र्स्ट ऑउट क्रिएट की।


2

एक और विकल्प अगर आपकी आईडी निरंकुश नहीं है और आपको पता है कि कौन सा सम्मिलित करना / अपडेट करना है:

$object = MyModel::findOrNew($id);
//assign attributes to update...
$object->save();

2

FirstOrCreate विधि की तरह, updateOrCreate मॉडल को बनाए रखता है, इसलिए सेव () कॉल करने की कोई आवश्यकता नहीं है।

// If there's a flight from Oakland to San Diego, set the price to $99.
// If no matching model exists, create one.

$flight = App\Flight::updateOrCreate(
   ['departure' => 'Oakland', 'destination' => 'San Diego'],
   ['price' => 99]
);

और अपने मुद्दे के लिए

$shopOwner = ShopMeta::updateOrCreate(
   ['shopId' => $theID, 'metadataKey' => '2001'],
   ['other field' => 'val' ,'other field' => 'val', ....]
);

1

वास्तव में FirstOrCreate उस स्थिति में अपडेट नहीं होगा जब रजिस्टर पहले से ही DB में मौजूद है। मैंने थोड़ा एरिक के समाधान में सुधार किया क्योंकि मुझे वास्तव में एक तालिका को अपडेट करने की आवश्यकता थी जिसमें न केवल कॉलम "आईडी" के लिए अद्वितीय मान हैं

/**
 * If the register exists in the table, it updates it. 
 * Otherwise it creates it
 * @param array $data Data to Insert/Update
 * @param array $keys Keys to check for in the table
 * @return Object
 */
static function createOrUpdate($data, $keys) {
    $record = self::where($keys)->first();
    if (is_null($record)) {
        return self::create($data);
    } else {
        return self::where($keys)->update($data);
    }
}

तो आप इसे इस तरह उपयोग करेंगे:

Model::createOrUpdate(
        array(
    'id_a' => 1,
    'foo' => 'bar'
        ), array(
    'id_a' => 1
        )
);

ऐसा नहीं करने में क्या अच्छा था: 1. कुंजी के आधार पर हटाएं, और 2. नए मूल्यों के साथ बनाएं। ये अभी भी 2 ऑपरेशन थे। क्या यह सृजन और विलोपन के मामले में अनुक्रमणिका को बचाने के लिए है?
हाफिज

1

जैसे @JuanchoRamone ऊपर पोस्ट किया गया है (धन्यवाद @Juancho) यह मेरे लिए बहुत उपयोगी है, लेकिन अगर आपका डेटा सरणी है तो आपको इस तरह थोड़ा संशोधित करना चाहिए:

public static function createOrUpdate($data, $keys) {
    $record = self::where($keys)->first();
    if (is_null($record)) {
        return self::create($data);
    } else {
        return $record->update($data);
    }
}

बस एक त्वरित नोट है कि यह createOrUpdate के बजाय अपडेट होना चाहिए
John Shipp

ठीक है, लेकिन अगर 1000 पंक्तियाँ हैं, तो यह 1000 प्रश्न होंगे?
Marcelo Agimóvel

0

क्या यह updateOrCreate () के समान नहीं है?

यह समान है लेकिन समान नहीं है। UpdateOrCreate () केवल एक बार में एक पंक्ति के लिए काम करेगा जो बल्क डालने की अनुमति नहीं देता है। InsertOnDuplicateKey कई पंक्तियों पर काम करेगा।

https://github.com/yadakhov/insert-on-duplicate-key


-2

जांचें कि कोई उपयोगकर्ता मौजूद है या नहीं। अगर नहीं डाला

$exist = DB::table('User')->where(['username'=>$username,'password'=>$password])->get();
if(count($exist)  >0) {
    echo "User already exist";;
}
else  {
    $data=array('username'=>$username,'password'=>$password);
    DB::table('User')->insert($data);
}
Laravel 5.4           

गुणवत्ता का जवाब प्रदान करने के लिए इस -कैसे-उत्तर पर एक नज़र SO.Take में आपका स्वागत है । ---
thewaywewere

कृपया उस फ्रेमवर्क को भी टैग करें जिसका आप उपयोग कर रहे हैं, php संस्करण, डेटाबेस।
जेसन जोसलिन

1
मैं Laravel 5.4, php7 और mysql का उपयोग कर रहा हूं
सबरीना आबिद

सबरीना यह एक आदर्श समाधान नहीं है क्योंकि ऐसा करने के लिए लार्वा में पहले से ही एक कार्य मौजूद है। लेकिन आपका एक सामान्य उपाय है
djangodude 16

इसकी पुरानी स्कूल विधि लार्वा में पहले से ही इसके लिए एक फ़ंक्शन है। चयनित उत्तर देखें
सईद अंसारी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.