2015-07-03 9 views
5

सबसे पहले, मैं आपको बताना चाहता हूं, मैंने इस समस्या को इंटरनेट की खोज की है और मैं इस समस्या को हल करने में सक्षम नहीं हूं।CONSTRAIN लार्वेल 5 स्कीमा बिल्डर पर अद्वितीय

मेरी समस्या मेरी तालिकाओं की प्राथमिक कुंजी के साथ है।

2 टेबल्स, घटनाओं और event_guest

+-----------+ 
| event  | 
+-----------+ 
| eventid | 
+-----------+ 

+-------------+ 
| event_guest | 
+-------------+ 
| guestid  | 
| eventid  | 
| firstname | 
| lastname | 
| email  | 
+-------------+ 

प्रत्येक घटना कई event_guest है है, लेकिन प्रत्येक अतिथि के ईमेल प्रत्येक घटना पर अद्वितीय होना चाहिए। यह प्रविष्टि रिकॉर्ड चाहिए ईमेल घटना पर सेट नहीं है

EventGuests::firstOrCreate(['eventid' => $eventid,'firstname' => 'Ivan', 'lastname'=>'Bravo', 'email'=>'[email protected]'); 

हैं:

मेरी नियंत्रक पर मैं मिलता है या EventGuest मॉडल पर firstOrCreate विधि का उपयोग कर बनाना चाहते हैं।

+-----------+----------+-----------+-----------+----------------+ 
| guestid | eventid | firstname | lastname | email   | 
+-----------+----------+-----------+-----------+----------------+ 
|   1 |  1 | Ivan  | Bravo  | [email protected] | 
+-----------+----------+-----------+-----------+----------------+ 

क्या मैं इसे eventid प्राथमिक कुंजी और guestidauto_increment क्षेत्र के रूप में तो यह प्रत्येक घटना पर 1 को रीसेट कर सकते हैं के रूप में है की जरूरत है। उदाहरण के लिए:

+-----------+----------+-----------+-----------+----------------+ 
| guestid | eventid | firstname | lastname | email   | 
+-----------+----------+-----------+-----------+----------------+ 
|   1 |  1 | Ivan  | Bravo  | [email protected] | 
|   2 |  1 | John  | Doe  | [email protected] | 
|   1 |  2 | Ivan  | Bravo  | [email protected] | 
+-----------+----------+-----------+-----------+----------------+ 

और मुझे डुप्लिकेट पंक्तियों को रोकने के लिए एक अद्वितीय फ़ील्ड के रूप में ईमेल की भी आवश्यकता है।

वर्तमान में मैं उपयोग कर रहा हूँ Laravel 5 माइग्रेशन, लेकिन यह इस त्रुटि का संकेत देता है जब मैं प्राथमिक क्षेत्रों रीसेट करने का प्रयास:

Schema::create('event_guest', function(Blueprint $table) { 
       $table->integer('guestid', true); 
       $table->integer('eventid'); 
       $table->integer('contactid')->nullable(); 
       $table->string('firstname', 256); 
       $table->string('lastname', 256); 
       $table->string('email', 256); 
       $table->unique(array('email','name')); 
       $table->primary(array('eventid','guestid')); 

      }); 

मैं वास्तव में मदद की जरूरत है:

Multiple primary key defined (SQL: alter table `event_guest` add primary key event_guest_eventid_guestid_primary(`eventid`, `guestid`))        

यह मेरा माइग्रेशन कोड है इसे ठीक से समझने के लिए।

मैं अतीत में कोई परेशानी नहीं का उपयोग कर था:

create table `event_guest` (
    `guestid` int(11) NOT NULL AUTO_INCREMENT, 
    `eventid` int(11) NOT NULL DEFAULT '0', 
    `firstname` varchar(255) NOT NULL, 
    `lastname` varchar(255) NOT NULL, 
    `email` varchar(255) NOT NULL, 
    PRIMARY KEY (`eventid`,`guestid`), 
    CONSTRAINT guest UNIQUE (eventid,email) 
) ENGINE=MyISAM 

अब

+1

अतिथि आईडी, प्रथम नाम, अंतिम नाम, और ईमेल को "अतिथि" नामक अपनी तालिका में तोड़ना संभव होगा। फिर 'event_guest' की स्कीमा को event_id और guest_id में बदलें? –

उत्तर

2

आपके प्रवास कोड के साथ 2 मुद्दों है कि आप तालिका आप की जरूरत बनाने से रोकने के हैं।

सबसे पहले, डिफ़ॉल्ट MySQL इंजन InnoDB है, जो समग्र प्राथमिक कुंजी पर ऑटो-वृद्धि को अस्वीकार करता है। इसलिए, आप MyISAM के लिए स्पष्ट रूप से इंजन स्थापित करने की आवश्यकता:

$table->engine = 'MyISAM'; 

दूसरे, जब आप ऑटो वेतन वृद्धि के लिए एक स्तंभ सेट, Laravel के स्कीमा निर्माता मान लिया गया यह प्राथमिक कुंजी है और वह स्तंभ प्राथमिक कुंजी बनाता है जब पैदा बयान बनाने । इसलिए जब अगली क्वेरी समग्र प्राथमिक कुंजी को परिभाषित करने का प्रयास करती है तो अतिथि अतिथि कॉलम पर पहले से मौजूद प्राथमिक कुंजी है - इसलिए डुप्लिकेट प्राथमिक कुंजी त्रुटि।

उस समस्या का समाधान अतिथि को मानक पूर्णांक कॉलम के रूप में परिभाषित करना है, समग्र कुंजी बनाएं और फिर अतिथि कॉलम अपडेट करें ताकि यह ऑटोइनक्रिकमेंट हो। दुर्भाग्य से स्कीमा बिल्डर कॉलम नाम बदलने के अलावा किसी भी अन्य ऑपरेशन का समर्थन नहीं करता है, इसलिए आपको अंतर्निहित डीबी परत का उपयोग करने और कच्ची क्वेरी निष्पादित करने की आवश्यकता है।

सारांश में, अपने माइग्रेशन कोड इस तरह दिखना चाहिए:

Schema::create('event_guest', function(Blueprint $table) { 
    $table->engine = 'MyISAM'; 
    $table->integer('guestid'); 
    $table->integer('eventid'); 
    $table->integer('contactid')->nullable(); 
    $table->string('firstname', 256); 
    $table->string('lastname', 256); 
    $table->string('email', 256); 
    $table->unique(array('email','name')); 
    $table->primary(array('eventid','guestid')); 
}); 

DB::statement('ALTER TABLE event_guest MODIFY guestid INTEGER NOT NULL AUTO_INCREMENT'); 
+0

मुझे केवल $ table-> अद्वितीय (सरणी ('ईमेल', 'नाम')) बदलना पड़ा; $ table-> अद्वितीय (सरणी ('अतिथि', 'ईमेल') के लिए); और मैं जाने के लिए अच्छा था! ... –

3

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

आपकी समस्या Event में कई Guest रों हो सकता है, और Guest कई Event रों हो सकती है। हम Laravel 5 में इस पेश कर सकते हैं, नीचे के रूप में *

event_guests

के लिए के लिए Guest

Schema::create('guests', function(Blueprint $table){ 
    $table->increments('id')->unsigned(); 
    $table->string('email')->unique(); 
    $table->string('password'); 
    $table->string('first_name'); 
    $table->string('last_name'); 
    $table->timestamps(); 
}); 

class Guest extends Model{ 

    public function events(){ 
     return $this->belongsToMany('App\Event','event_guests'); 
    } 

} 

प्रवासन प्रवासन और मॉडल के लिए Event

Schema::create('events', function(Blueprint $table){ 
    $table->increments('id')->unsigned(); 
    $table->string('title'); 
    $table->string('venue'); 
    $table->text('description'); 
    $table->timestamps(); 
}); 

class Event extends Model{ 

    public function guests(){ 
     return $this->belongsToMany('App\Guest', 'event_guests'); 
    } 

} 

प्रवासन और मॉडल

Schema::create('event_guests', function(Blueprint $table){ $table->increments('id'); $table->integer('event_id')->unsigned(); $table->integer('guest_id')->unsigned()->nullable(); $table->foreign('guest_id')->references('id')->on('guests')->onDelete('cascade'); $table->foreign('event_id')->references('id')->on('events')->onDelete('cascade'); }); 

अब सदस्यता लेने GuestEvent को

$event = Event::create([ 
      'title' => 'Laracon', 
      'venue' => 'Hotel XYZ, New York', 
      'description' => 'Drink is not free' 
     ]); 
$guest = Guest::findOrFail($guestId); 
$guest2 = Guest::findOrFail($guestId2); 

$event->guests()->sync([$guestId->id, $guestId2->id], false); //`false` as second argument prevents `sync` from detaching previous associations 

इस stetagy में नीचे के रूप में के रूप में आसान है, आप किसी भी दोहराव के बिना समर्पित तालिकाओं के लिए event और guest डेटा अलग और बहुत आसानी से विशिष्टता की कमी बनाए रख सकते हैं। और आप अपने संबंध जहाजों को बनाए रखने के लिए पिवट तालिका बनाते हैं।

Read More लैरवेल रिलेशनशिप के बारे में।

+0

आपके उत्तर के लिए बहुत बहुत धन्यवाद, मैंने इस परियोजना को इस तरह से शुरू किया, अलग-अलग तालिकाओं का निर्माण और संबंध बनाने, बहुत तार्किक और अच्छी तरह लिखा है। मेरे आवेदन में बाधाओं के साथ समस्या यह है कि, अतीत में मुझे पंजीकृत उपयोगकर्ताओं पर भी विचार करने के लिए कहा गया था, ताकि वे अतिथि मेहमानों का हिस्सा बन सकें ... इसलिए, जब मैंने ऐप को लार्वेल में माइग्रेट किया, तो डीबी संरचना को बनाए रखने के लिए समस्याएं शुरू हुईं और डेटा, मुझे माइग्रेशन बनाना था क्योंकि वे अन्य डेटाबेस में थे। +1 मैं अन्य उपयोगकर्ताओं और सर्वोत्तम अभ्यास के लिए आपके दृष्टिकोण की सिफारिश करता हूं, लेकिन इस मामले में jedrzej.kurylo का सुझाव मेरे लिए काम करता है! –

संबंधित मुद्दे