Я создаю сайт, который позволяет пользователям перечислить до 5 компаний, с которыми они связаны. Когда другие пользователи ищут эти компании, все пользователи, связанные с этой компанией, будут отображаться в результатах поиска.
Компании будут представлены пользователями через текстовое поле ввода.
Как избежать предоставления пользователям дублирующих компаний? Например, если UserA отправляет компанию под названием stackoverflow, тогда появляется UserB, а также отправляет stackoverflow, в моей базе данных будет 2 stackoverflow.
У меня 3 таблицы:
Таблица пользователей
идентификатор | имя пользователя | адрес электронной почты
Стол компании
id | название компании
ПользователиКомпания стола
идентификатор | идентификатор пользователя | CompanyID
Я использую Laravel 5
Вы действительно должны использовать Laravel Validation и ключевое слово, unique
для обработки этого:
$this->validate($request, [ 'company' => 'required|unique:company|max:255' ]);
Кроме того, вы можете использовать собственный класс запроса для обработки проверки формы :
public function rules() { return [ 'company' => 'required|unique|max:255' ]; }
Если бы я был вами, я бы использовал второй.
Вы можете сделать это с простой проверкой. Если компания не существует, создайте новую компанию или приложите компанию к пользователю.
Я предполагаю, что компании представлены в виде одного ввода текста, разделенного запятыми, и вы правильно настроили свои отношения. Если не проверить это .
Пример:
// Inside your controller public function post_something(Request $request) { // Always good to validate $this->validate(....); // Somehow get your user model $user = .... // Get companies input and loop $company_names = $request->input('company_names'); $company_names = explode(',', $company_names ); foreach ($company_names as $company_name) { $company = Company::firstOrCreate(['company_name' => $company_name]); $user->companies()->attach($company); } // Your other stuff // .... }
Это может быть достигнуто путем создания PRIMARY Key или UNIQUE на company_Name
ALTER TABLE company_Table ADD PRIMARY KEY(company_Name) ALTER TABLE company_Table ADD UNIQUE (company_Name)
или
IF NOT EXISTS(QUERY) Then INSERT
или
Создайте триггер ДО НАЧАЛА ВСТАВКИ.
http://dev.mysql.com/doc/refman/5.7/en/trigger-syntax.html
Вы можете добавить уникальный индекс в таблицу. Поэтому, если ваша колонка называется company_name
а таблица – это companies
вы можете выполнить следующее:
alter table companies add unique (company_name)
Или, альтернативно, вы можете сделать запрос в программировании, прежде чем разрешить вставку, которая проверяет, существует ли запись. Или комбинация обоих ..
вы можете использовать уникальный ключ для таблицы компаний http://dev.mysql.com/doc/refman/5.7/en/constraint-primary-key.html
Это очень легко получить, используя UNIQUE
в MySQL.
ALTER TABLE `company_Table` ADD UNIQUE ( `company_Name` )
Помещая это в MySQL, столбец company_Name становится UNIQUE
, то есть может быть только один. Если вы попытаетесь вставить еще один, появится ошибка.
UNIQUE
также может использоваться для электронных писем участника на пользовательской базе, если вы не хотите, чтобы кто-то входил в систему с тем же адресом электронной почты. UNIQUE
также идеально подходит для POST_ID, MEMBER_ID, COMMENT_ID и некоторых других, которые могут стать очень полезными на блоге, форуме или в социальных сетях.
Если вы хотите создать ключ UNIQUE
при создании этой таблицы, вот как вы это сделаете:
CREATE TABLE Company_Table ( ID int NOT NULL, Company_Name varchar(255), UNIQUE (Company_Name) )
У W3schools есть хороший учебник по этому поводу: здесь
По моему мнению, вы должны использовать метод Eloquent firstOrCreate
Если вы будете использовать этот подход, вам даже не понадобится «уникальная» проверка под компаниями.
Схема БД
users id username companies id company_name user_company id user_id company_id
Модели (только методы отношений)
User.php
public function companies() { return $this->belongsToMany('NAMESPACE_TO_YOUR_MODEL\Company'); /*you can set foreign keys fields if it's not canonical see docs*/ }
Company.php
public function users() { return $this->belongsToMany('NAMESPACE_TO_YOUR_MODEL\User'); }
контроллер
public function store(CompanyRequest $request) { $companiesFromRequest = $request->get('companies'); // it's just for example, you can retreive companies from request with any other approach $companiesId = []; foreach ($companiesFromRequest as $company) { // assumes that $company variable contains all or at least part of info, // that need to create or identify particuliar comapny $c = Company::firstOrCreate($company); $companiesId[] = $c->id; } // in this case we just retreive existing user $user = User::findOrFail($request->get('user_id')); $user->companies()->sync($companiesId); // or you can use // $user->companies()->attach($companiesId); // difference between this commands you can found in official laravel docs return redirect('any/place/you/wish') }
Application Layer: Использовать свойство валидации Laravel 'unique', чтобы установить, что разрешено только уникальное название компании.
public function store(Request $request) { $this->validate($request, [ 'company_name' => 'required|unique:companies|max:255', ]); // The company name is valid, store in database... }
Уровень базы данных: добавьте ограничение как уникальное для миграции таблицы компании для столбца company_name.
$table->string('company_name')->unique();
нашел ответ в larval, я просто использую метод firstOrNew (), который попытается найти запись в базе данных, соответствующей заданным атрибутам. Однако, если модель не найдена, будет возвращен экземпляр новой модели. Обратите внимание, что модель, возвращаемая firstOrNew, еще не сохраняется в базе данных. Чтобы сохранить его, вам необходимо вызвать save вручную:
как указано здесь
Попробуйте построить схему следующим образом, чтобы получить оптимальную производительность. Эта структура помогает избежать дублирования данных, а также выполнять проверки кода в Laravel, чтобы избежать вредоносных входов.
CREATE TABLE IF NOT EXISTS `Users Table` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `username` varchar(255) NOT NULL, `email` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1; CREATE TABLE IF NOT EXISTS `Company Table` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `company name` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `company name` (`company name`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1; CREATE TABLE IF NOT EXISTS `Users Company Table` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `userID` int(11) unsigned NOT NULL, `companyID` int(11) unsigned NOT NULL, PRIMARY KEY (`id`), KEY `userID` (`userID`), KEY `companyID` (`companyID`), CONSTRAINT `Users Company Table_ibfk_1` FOREIGN KEY (`userID`) REFERENCES `Users Table` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `Users Company Table_ibfk_2` FOREIGN KEY (`companyID`) REFERENCES `Company Table` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
Надеюсь, этот код поможет вам. Это код sql для вставки уникальных данных
INSERT INTO UsersCompanyTable (userID, companyID) SELECT * FROM (SELECT $_POST("user_id"), $_POST("company_id")) AS tmp WHERE NOT EXISTS ( SELECT companyID FROM UsersCompanyTable WHERE companyID = $_POST("company_id") ) LIMIT 1;
Вы должны разрешить пользователю выбирать компанию, а затем просто указывать ссылки на таблицы UserID, CompanyID
в таблице UsersCompany. Таким образом, вы всегда будете иметь уникальную запись, если UserA вставляет StackOverFlow, а UserB также вставляет StackOverFlow в вашу базу данных. Это будет выглядеть так:
Или, если вы хотите, чтобы пользователь входил в компанию, проверьте, существует ли та или иная компания:
var checkcompany= "select * from Company Table where company name=company name"
Затем проверка
if(checkcompany ! =null)
Затем вставьте запись или проигнорируйте ее.