লারাভেল স্পষ্টতত তৈরি এবং আপডেট করুন


164

নতুন রেকর্ড সন্নিবেশ করা বা এটি বিদ্যমান থাকলে আপডেট করার শর্টহ্যান্ড কী?

<?php

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

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

আমি অনুমান করছি shopIdআপনার প্রাথমিক কী না, তাই না?
সের্গিউ প্যারাশিভ

@ সার্জিউপারাশিচিভ, হ্যাঁ এটি নয়
মাইবি

উত্তরটি ইরিকডে ডেভেলপার থেকে দেখুন। এটি একটি দুর্দান্ত এমবেডেড বোধক পদ্ধতি দেখায় যা কাজটি করা উচিত।
cw24

সঠিক একই জিনিস সম্পূর্ণরূপে নীচের লিঙ্কে উত্তর হয় stackoverflow.com/questions/18839941/...
Bashirpour

উত্তর:


232

"লু সিপ" কী সম্পর্কে কথা বলছিল তার একটি সম্পূর্ণ উদাহরণ এখানে:

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

নীচে লারাভেলের সর্বশেষতম সংস্করণে থাকা ডক্সের আপডেট লিঙ্কটি রয়েছে

এখানে ডক্স: আপডেট হওয়া লিঙ্ক


1
ঠিক! 'firstOrNew' এছাড়াও 4.0 এ উপস্থিত রয়েছে (দস্তাবেজে এর উল্লেখ নেই)
younes0

2
এছাড়াও আমরা ($ ব্যবহারকারী-> বিদ্যমান) ব্যবহার করে $ ব্যবহারকারী নতুন / পুনরুদ্ধার করা হয়েছে তা পরীক্ষা করতে পারি।
রিউ_হায়াবুসা

1
@ রিউ_হায়াবুসা এর ফলে সম্ভবত জাতি পরিস্থিতি সৃষ্টি হবে
ক্রিস হ্যারিসন

নতুন সিনট্যাক্সটি 5 বা 5.5 সংস্করণে
ব্যবহারকারী1204214

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;
    }

পুরানো উত্তর নীচে


আমি ভাবছি যে এটি করার জন্য কোনওভাবে এল 4 কার্যকারিতা রয়েছে কিনা:

$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_


এটি রয়েছে এবং এটি প্রথম ওআরএনইউ / ফার্স্টসঅরক্রিয়েট বলা হয়
ম্যালহাল

@ ম্যালকমল আমি উপরের উত্তর আপডেট করেছি। এটিতে দেখা গেছে যে বুদ্ধিমানের অনেকগুলি বৈশিষ্ট্য রয়েছে যা আমি নিজেকে পুনর্নির্মাণের জন্য পেয়েছি;)
ডক্সটি

প্যাকেজিস্টের 4.2.0 (স্থিতিশীল 2014/6/1) এ আপডেটঅরক্রিয়েট নেই। তবে এটি উত্সের দিকে তাকিয়ে বাস্তবায়ন করতে পারে। ModelName::firstOrNew(['param' => 'condition'])->fill(Input::get())->save();এটা করা উচিত।
বিবিস্তায়

3
কেবল লক্ষ্য করুন যে লারাভেল এটিকে লেনদেন হিসাবে চালায় না, সুতরাং আপনার যদি অনন্য কী থাকে এবং অন্য কোনও ব্যবহারকারী একই সাথে একই কী তৈরি করে তবে আপনি ব্যতিক্রম পেতে পারেন। আমি বিশ্বাস করি যে রেডবিয়ানপিএইচপির অন্যতম সুবিধা হ'ল এই ধরণের জিনিসটি আপনার জন্য লেনদেনে করা হয়।
মালহাল

ভরাটের ব্যবহারটি নির্দেশ করার জন্য ধন্যবাদ () যা আমাকে ব্যাপকভাবে সহায়তা করেছে!
সাইপ্রাসে

70

2020 আপডেট

মতই Laravel> = 5.3 , কেউ এখনো সহজ ভাবে তা করতে কিভাবে জানতে আগ্রহী হলে। তার ব্যবহার করে সম্ভব: updateOrCreate()

জিজ্ঞাসিত প্রশ্নের উদাহরণস্বরূপ আপনি এমন কিছু ব্যবহার করতে পারেন:

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

উপরে কোড শপমেটা দ্বারা প্রতিনিধিত্ব করা সারণীটি পরীক্ষা করবে, যা সম্ভবত 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বা এটির ডিফল্ট মান নেই possible

আরও রেফারেন্সের জন্য দয়া করে লারাভেল ডকুমেন্টেশন দেখুন: 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]
);

যা প্রায় সবকিছু পরিষ্কার করে দেয়।

অনুসন্ধানী নির্মাতা আপডেট

কেউ জিজ্ঞাসা করেছেন যে লারাভেলে কোয়েরি বিল্ডার ব্যবহার করা সম্ভব কিনা। লারাভেল ডক্স থেকে ক্যোয়ারী বিল্ডারের জন্য এখানে উল্লেখ রয়েছে।

ক্যোয়ারি বিল্ডার এলওভার্টের মতো ঠিক একইভাবে কাজ করে তাই যে কোনও কিছু যা এলওভারেন্টের জন্য সত্য তা কোয়েরি বিল্ডারের ক্ষেত্রেও সত্য। সুতরাং এই নির্দিষ্ট ক্ষেত্রে, আপনার কোয়েরি বিল্ডারের সাথে কেবল একই ফাংশনটি ব্যবহার করুন:

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

অবশ্যই, ডিবি মুখোমুখি যুক্ত করতে ভুলবেন না:

use Illuminate\Support\Facades\DB;

অথবা

use DB;

আমি আসা করি এটা সাহায্য করবে


কীভাবে জিজ্ঞাসা নির্মাতা?
আকাশ

এটা কেমন ? :)
শিক্ষার্থী

আমি কোয়েরি বিল্ডারের সাথে একই জিনিসটি করতে চাই। সুস্পষ্ট নয়। এটা কি সম্ভব?
আকাশ

আমার উত্তর আপডেট করেছে, উপরের উত্তরের "ক্যোয়ারী বিল্ডার আপডেট" বিভাগটি অনুসন্ধান করুন।
লার্নার

আমি ডিবি :: টেবিল ('শপ_মেটাস') :: আপডেটঅরক্রিয়েট পদ্ধতিটি চেষ্টা করেছি তবে এটি আমাকে ম্যাক্রোয়েবল.এফপি লাইন 59-এ BadMethodCallException এর পরে নিম্নলিখিত ত্রুটি দেয়: পদ্ধতি আপডেটঅর্ডারেটরটি বিদ্যমান নেই। যদিও আমি ডিবি ব্যবহার করি;
স্বপ্নিল শেন্দে

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

প্রথমআরক্রিয়াট পদ্ধতির মতো, আপডেটআরক্রিয়েট মডেলটি ধরে রাখে, তাই সংরক্ষণের কল করার দরকার নেই ()

// 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

প্রকৃতপক্ষে ডিবিতে রেজিস্টার ইতিমধ্যে বিদ্যমান থাকলে ফার্স্টআরক্রিয়েট আপডেট করবে না । আমি এরিকের সমাধানটি কিছুটা উন্নত করেছি কারণ আমার এমন একটি টেবিলটি আপডেট করা দরকার যা কেবলমাত্র "আইডি" কলামের জন্যই নয় তার অনন্য মূল্য রয়েছে

/**
 * 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

@ জুয়ানচোরামোন যেমন উপরে পোস্ট করেছেন (ধন্যবাদ @ জুঞ্চো) এটি আমার পক্ষে খুব উপকারী তবে আপনার ডেটা অ্যারে থাকলে আপনার এইরকম কিছুটা পরিবর্তন করা উচিত:

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

কেবলমাত্র একটি দ্রুত দ্রষ্টব্য যে এটি তৈরিরআউডপেটের পরিবর্তে আপডেটঅর্ডারেট হওয়া উচিত
জন শিপ

ঠিক আছে তবে যদি 1000 সারি থাকে তবে এটি 1000 ক্যোয়ারী চলবে?
মার্সেলো আগিমিভেল

0

এটি কি আপডেটআরক্রিয়েট () এর মতো নয়?

এটি একই তবে একই নয়। আপডেটআরক্রিয়েট () কেবল এমন এক বারে এক সারিটির জন্য কাজ করবে যা বাল্ক প্রবেশের অনুমতি দেয় না। InsertOnDuplicateKey অনেক সারিতে কাজ করবে।

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


-2

ব্যবহারকারীর উপস্থিতি আছে কি নেই তা পরীক্ষা করুন। Inোকানো না হলে

$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 এই কটাক্ষপাত স্বাগতম কিভাবে-থেকে-উত্তর গুণমানের উত্তর প্রদানের জন্য। ---
ওয়েওয়েওয়েরে

আপনি যে ফ্রেমওয়ার্কটি ব্যবহার করছেন তা, পিএইচপি সংস্করণ, ডাটাবেস ট্যাগ করুন।
জেসন জোসলিন

1
আমি লারাভেল 5.4, পিএইচপি 7 এবং মাইএসকিএল
আবিদ

সাব্রিনা এটি আদর্শ সমাধান নয় কারণ এটি করার জন্য লারাভেলে একটি ফাংশন ইতিমধ্যে বিদ্যমান। তবে আপনার একটি সাধারণ সমাধান
জাঙ্গোদুদ

এর পুরানো স্কুল পদ্ধতি লারাভেলের ইতিমধ্যে এটির জন্য একটি ফাংশন রয়েছে। নির্বাচিত উত্তর দেখুন
Saeed
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.