लारावेल में MassAssignmentException


108

मैं एक लारावेल नौसिखिया हूं। मैं अपने डेटाबेस को सीड करना चाहता हूं। जब मैं बीज कमांड चलाता हूं तो मुझे एक अपवाद मिलता है

  [Illuminate\Database\Eloquent\MassAssignmentException]
  username



db:seed [--class[="..."]] [--database[="..."]]

मैं क्या गलत कर रहा हूं। मेरे द्वारा उपयोग की जाने वाली कमांड है:

php artisan db:seed --class="UsersTableSeeder"

मेरा बीज वर्ग इस प्रकार है:

class UsersTableSeeder extends Seeder {
    public function run()
    {
            User::truncate();
            User::create([
                'username' => 'PaulSheer',
                'email' => 'psheer@rute.co.za',
                'password' => '45678'
            ]);

            User::create([
                'username' => 'Stevo',
                'email' => 'steve@rute.co.za',
                'password' => '45678'
            ]);
    }
}

जवाबों:


231

लारवेल डॉक का यह खंड पढ़ें: http://laravel.com/docs/eloquent#mass-assignment

Laravel डिफ़ॉल्ट रूप से बड़े पैमाने पर असाइनमेंट सुरक्षा मुद्दों के खिलाफ एक सुरक्षा प्रदान करता है। इसलिए आपको मैन्युअल रूप से परिभाषित करना होगा कि कौन से फ़ील्ड "बड़े पैमाने पर असाइन किए गए" हो सकते हैं:

class User extends Model
{
    protected $fillable = ['username', 'email', 'password'];
}

चेतावनी: सावधान रहें जब आप महत्वपूर्ण क्षेत्रों जैसे passwordया के बड़े असाइनमेंट की अनुमति देते हैं role। यह एक सुरक्षा समस्या पैदा कर सकता है क्योंकि जब आप नहीं चाहते हैं तो उपयोगकर्ता इस फ़ील्ड मान को अपडेट करने में सक्षम हो सकते हैं।


7
-1 जबकि यह काम करता है, Pascalculator से समाधान बेहतर है कि यह अन-गार्ड तभी करता है जब बड़े पैमाने पर असाइनमेंट की जरूरत हो, न कि आवेदन के जीवनकाल के लिए।
एमग्रिंस

1
आप सही हैं, डेटाबेस सीडिंग के विशिष्ट संदर्भ में, केवल बोने के दौरान इसे बेहतर बनाना चाहिए। लेकिन, क्योंकि यह उत्तर एक संदर्भ विषय बन गया लगता है MassAssignmentExceptionऔर क्योंकि यह लगता है कि मेरा उत्तर एक अच्छा सामान्य समाधान है, मैं इसे वैसे ही रखूंगा।
एलेक्जेंडर ब्यूटिंस्की

अलेक्जेंड्रे, मुझे आपके तर्क का पालन करना मुश्किल हो रहा है। यदि आप सहमत हैं, तो आप अपना स्वयं का उत्तर भी बदल सकते हैं, और भी अधिक क्योंकि यह एक संदर्भ विषय बन रहा है। आपके द्वारा सुझाया गया उत्तर वास्तव में काम करेगा, लेकिन लारवेल सम्मेलन के अनुपालन में नहीं है।
पास्कलकुलर

4
मैं अपना उत्तर इस प्रकार रखता हूं क्योंकि मुझे लगता है कि यह एक अच्छा सामान्य पैटर्न है (मैं इसे अपनी परियोजनाओं में उपयोग करता हूं) और क्योंकि मुझे लगता है कि यह आपके उत्तर की तुलना में लारवेल सम्मेलन के अनुपालन में अधिक या कम नहीं है (देखें डॉक)। लेकिन, क्योंकि राय की बहुलता महान है और क्योंकि आपका समाधान मेरा जितना अच्छा हो सकता है, मैंने इसे उकेरा है और मैं दूसरों को इसे पढ़ने के लिए प्रोत्साहित करता हूं :)
अलेक्जेंडर ब्यूटिंस्की

'पासवर्ड' => bcrypt ( '45678')
Douglas.Sesar

31

मैं लारवेल 4.2 का उपयोग कर रहा हूं।

त्रुटि आप देख रहे हैं

[Illuminate\Database\Eloquent\MassAssignmentException]
username

वास्तव में क्योंकि डेटाबेस को एन मास्क भरने से सुरक्षित किया जाता है, जो कि आप तब कर रहे होते हैं जब आप बीजारोपण कर रहे होते हैं। हालांकि, मेरी राय में, यह घोषित करना आवश्यक नहीं है (और असुरक्षित हो सकता है) कि आपके मॉडल में कौन से फ़ील्ड भरने योग्य होने चाहिए, अगर आपको केवल एक बीजर को निष्पादित करने की आवश्यकता है।

आपके सीडिंग फ़ोल्डर में आपके पास डेटाबेससाइडर क्लास है:

class DatabaseSeeder extends Seeder {

    /**
    * Run the database seeds.
    *
    * @return void
    */

    public function run()
    {
        Eloquent::unguard();

        //$this->call('UserTableSeeder');
    }
}

यह वर्ग एक मुखौटा के रूप में कार्य करता है, उन सभी बीजों को सूचीबद्ध करता है जिन्हें निष्पादित करने की आवश्यकता होती है। यदि आप UserTableSeeder सीडर को कारीगर के माध्यम से मैन्युअल रूप से कॉल करते हैं, जैसे आपने php artisan db:seed --class="UsersTableSeeder"कमांड के साथ किया था , तो आप इस DatabaseSeeder वर्ग को बायपास करते हैं।

इस DatabaseSeeder वर्ग में कमांड Eloquent::unguard();सभी तालिकाओं पर अस्थायी बड़े पैमाने पर असाइनमेंट की अनुमति देता है, जो कि आपको डेटाबेस की सीडिंग करते समय ठीक उसी प्रकार की आवश्यकता होती है। जब आप php aristan db:seedकमांड चलाते हैं, तो यह अनजाने तरीके को निष्पादित किया जाता है , इसलिए यह आपके मॉडल में फ़ील्ड को भरने योग्य बनाने के विपरीत अस्थायी है (जैसा कि स्वीकृत और अन्य उत्तरों में कहा गया है)।

आपको बस $this->call('UsersTableSeeder');डेटाबेससेडर क्लास में रन विधि को जोड़ने और php aristan db:seedअपने सीएलआई में चलाने की ज़रूरत है जो डिफ़ॉल्ट रूप से डेटाबेससेडर को निष्पादित करेगा।

यह भी ध्यान दें कि आप एक बहुवचन वर्गनाम उपयोगकर्ताओं का उपयोग कर रहे हैं, जबकि लारवल एकवचन रूप उपयोगकर्ता का उपयोग करते हैं। यदि आप अपनी कक्षा को पारंपरिक एकवचन के रूप में बदलने का निर्णय लेते हैं, तो आप बस उसे अनइंस्टॉल कर सकते हैं //$this->call('UserTableSeeder');जो पहले ही असाइन किया गया है, लेकिन डेटाबेससेडर वर्ग में डिफ़ॉल्ट रूप से टिप्पणी की गई है।


4
पैरानॉयड, और प्यूरिस्ट्स के लिए: आपको \Eloquent::reguard();अपने मास असाइनमेंट्स के पूरा होने के बाद उपयोग करने के लिए सराहना मिलेगी ।
सेंटरऑर्बिट

10

सभी क्षेत्रों को भरने योग्य बनाने के लिए , बस अपनी कक्षा पर घोषणा करें:

protected $guarded = array();

यह आपको प्रत्येक क्षेत्र को घोषित किए बिना भरण पद्धति को कॉल करने में सक्षम करेगा।


7

बस Eloquent::unguard();जब आप एक बीज करते हैं, तो रन विधि के शीर्ष में जोड़ दें , $fillableआपको उन सभी मॉडलों में एक सरणी बनाने की कोई आवश्यकता नहीं है जो आपके पास है।

आम तौर पर यह पहले से ही DatabaseSeederकक्षा में निर्दिष्ट है । हालाँकि, क्योंकि आप UsersTableSeederसीधे फोन कर रहे हैं:

php artisan db:seed --class="UsersTableSeeder"

Eloquent::unguard(); नहीं कहा जा रहा है और त्रुटि देता है।



1

मुझे MassAssignmentException मिल रही थी जब मैंने अपने मॉडल को इस तरह बढ़ाया है।

class Upload extends Eloquent {

}

मैं इस तरह से सरणी डालने की कोशिश कर रहा था

Upload::create($array);//$array was data to insert.

जब मैंने अपलोड मॉडल बनाया है तो समस्या का समाधान हो गया है

class Upload extends Eloquent {
    protected $guarded = array();  // Important
}

संदर्भ https://github.com/aidkit/aidkit/issues/2#issuecomment-21055670


1

आपकी नियंत्रक फ़ाइल में उपयोगकर्ता उचित मॉडल।

<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\User;

0

यदि आपके पास डेटाबेस पर तालिका और फ़ील्ड हैं तो आप बस इस कमांड का उपयोग कर सकते हैं:

php artisan db:seed --class=UsersTableSeeder --database=YOURDATABSE

0

जब आप डेटाबेस को सीडिंग करना चाहते हैं तो यह एक अच्छा तरीका नहीं है। फैकर का
उपयोग करेंहार्ड कोडिंग के बजाय , और इस सब से पहले शायद तालिकाओं को छोटा करना बेहतर है।

इस उदाहरण पर विचार करें:

    // Truncate table.  
    DB::table('users')->truncate();

    // Create an instance of faker.
    $faker = Faker::create();

    // define an array for fake data.
    $users = [];

    // Make an array of 500 users with faker.
    foreach (range(1, 500) as $index)
    {
        $users[] = [
            'group_id' => rand(1, 3),
            'name' => $faker->name,
            'company' => $faker->company,
            'email' => $faker->email,
            'phone' => $faker->phoneNumber,
            'address' => "{$faker->streetName} {$faker->postCode} {$faker->city}",
            'about' => $faker->sentence($nbWords = 20, $variableNbWords = true),
            'created_at' => new DateTime,
            'updated_at' => new DateTime,
        ];
    }

    // Insert into database.
    DB::table('users')->insert($users);

0

लार्वा को बताने के लिए भराव का उपयोग करें कि कौन से फ़ील्ड को सरणी का उपयोग करके भरा जा सकता है। डिफ़ॉल्ट रूप से, लारवेल डेटाबेस फ़ील्ड को एक सरणी के माध्यम से अपडेट करने की अनुमति नहीं देता है

Protected $fillable=array('Fields you want to fill using array');

के विपरीत fillable है guardable


-1

यदि आप डालने की OOP विधि का उपयोग करते हैं, तो आपको बड़े पैमाने पर कार्रवाई / भरण गुणों के बारे में चिंता करने की आवश्यकता नहीं है:

$user = new User;
$user->username = 'Stevo';
$user->email = 'steve@rute.co.za';
$user->password = '45678';
$user->save();
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.