Change default column name 'id' when validating - laravel

I am trying to validate an email field so that I make sure it's unique, but not in a row with a certain id, which I do like so:
'email' => 'required|email|unique:seller_user,email,'.$seller_id,
That works, but it automatically searches for a column named id, whereas in my table that column is actually called seller_id, so how can I change that?

You can specify the field to search using the fourth parameter to the rule:
'email' => 'required|email|unique:seller_user,email,'.$seller_id.',seller_id',

Related

Problem with adding record to database after seeds in Laravel

I add test records to the database using seeds
public function run()
{
DB::table('categories')->insert([
['id' => 1,'name' => 'Select a category', 'slug' => null],
['id' => 2,'name' => 'Computers', 'slug' => 'computer-&-office'],
]);
}
But then, if I want to add a new record to the database, already through the form, I get the error
SQLSTATE[23505]: Unique violation: 7 ERROR: duplicate key value violates unique constraint "categories_pkey"
I understand that when I add a new record through the form, it is created with id = 1, and I already have this id in the database. How can I avoid this error?
You should remove id from insert() and make it auto increment in mysql,
It complains about a unique constraint, meaning your primary key is indexed as "categories_pkey" or you have another field that is unique.
This happens because you are inserting a record and a record already exists where that column must be unique.
In general production workflow, when you add a record you never specify an ID. Most cases (there are exceptions) ID is an autoincrement integer, meaning it adds up automatically. On the first insert the database set its ID to 1, the second to 2 and so on.
As a seeder, its generally a good idea to set up the ID so you know that a certain ID matches a certain item (as a base content of a project like user states or roles).
As a regular workflow (from a form submission), you can have something like this
DB::table('categories')->insert([
['name' => 'some value', 'slug' => 'some slug']
]);
However, I don't advise to use DB::table when Laravel provides ActiveRecords pattern (ORM, called Eloquent) which you should take a look here.
https://laravel.com/docs/8.x/eloquent#introduction
Besides the benefits of layer abstraction and working with activerecords, It produces a much cleaner code like
$data = ['slug' => 'some slug', 'name' => 'some name'];
Category::create($data);

What do "except" and "idColumn" refers in "unique:table,column,except,idColumn"? from Laravel docs

To validate the update of the e-mail of a user already registered I have the next function to exclude the "unique" rule for the current User:
public function updateRules() {
return [
'name' => 'required',
'email' => 'required|unique:users,email,'.$this->id,
];
}
In the Laravel docs https://laravel.com/docs/5.7/validation#rule-unique I found the syntax unique:table,column,except,idColumn with 4 parameters:
table: refers to the table name "users"
column: refers the column name "email"
except: I'm taking it as the id of the Model instance I want to exclude from the "unique" verification
idColumn: I have no idea about this
Someone could clarify what do except and idColumn refers to?
Note for those obsessed with duplicate questions: I'm not asking how to do the rule exclusion for the update, because it seems to work just fine, I've read those questions and answers. I'm making helper functions and I need to know exactly what those two parameters means.
So you are right about the except parameter, it is the id that you want to be excluded from the check.
And idColumn is optional in case your column is not called id but user_id for example. So you will use:
'required|unique:users,email,'.$this->id . ',user_id';

I get duplicate entries with the attach method in Laravel 5. Not sure what the problem is

So I'm trying to attach id's with some meta data to a pivot table in Laravel 5.
For some reason, I get the two inserts where there should be one, and the wrong ID's being inserted the second time round.
I'm not sure if there is something I might be missing here.
This is the code:
$match_values = array(
'dataId' => $result->id,
'dataMetaId' => $the_meta->id
);
$result->campaignDataMeta()->attach($match_values, [
'meta_value' => $value
]);
The database structure consists of a main campaignData table for email campaigns, a campaignDataMeta table (id, timestamps, name) for email meta data names, and a lookup table campaignDataMatches (id, campaignDataId, campaignDataMetaId, meta_value).
In campaignDataMatches I get the campaignDataId value sometimes being inserted into the campaignDataMeta column.
I've solved the problem.
Apparently had to add the relevant ID (in this case the dataMetaId) within the attach parameter.
Like this:
$result->dataMeta()->attach([$data_meta_id => [
'meta_value' => $value
]]);
Check the database columns primary maybe the dataId and metaId are both primary.

laravel validation check field equal something

how to check a field is exactly equal to a string or number
I want to check a field named course_id is equal a field of database id in course database. now I want to check if course_id is equal to id.
You can validate it by using the exists validation rule:
$validationRules = ['course_id' => 'exists:course,id'];
create rule as below and use validator on input
$rules = array(
'id' => 'exists:your_table_name'
);
for more help
https://laravel.com/docs/5.2/validation#rule-exists

First Or Create

I know using:
User::firstOrCreate(array('name' => $input['name'], 'email' => $input['email'], 'password' => $input['password']));
Checks whether the user exists first, if not it creates it, but how does it check? Does it check on all the params provided or is there a way to specifiy a specific param, e.g. can I just check that the email address exists, and not the name - as two users may have the same name but their email address needs to be unique.
firstOrCreate() checks for all the arguments to be present before it finds a match. If not all arguments match, then a new instance of the model will be created.
If you only want to check on a specific field, then use firstOrCreate(['field_name' => 'value']) with only one item in the array. This will return the first item that matches, or create a new one if not matches are found.
The difference between firstOrCreate() and firstOrNew():
firstOrCreate() will automatically create a new entry in the database if there is not match found. Otherwise it will give you the matched item.
firstOrNew() will give you a new model instance to work with if not match was found, but will only be saved to the database when you explicitly do so (calling save() on the model). Otherwise it will give you the matched item.
Choosing between one or the other depends on what you want to do. If you want to modify the model instance before it is saved for the first time (e.g. setting a name or some mandatory field), you should use firstOrNew(). If you can just use the arguments to immediately create a new model instance in the database without modifying it, you can use firstOrCreate().
As of Laravel 5.3 it's possible to do this in one step with firstOrCreate using a second optional values parameter used only if a new record is created, and not for the initial search. It's explained in the documentation as follows:
The firstOrCreate method will attempt to locate a database record using the given column / value pairs. If the model cannot be found in the database, a record will be inserted with the attributes resulting from merging the first array argument with the optional second array argument.
Example
$user = User::firstOrCreate([
'email' => 'dummy#domain.example'
], [
'firstName' => 'Taylor',
'lastName' => 'Otwell'
]);
This returns the User for the specified email if found, otherwise creates and returns a new user with the combined array of email, firstName, and lastName.
This technique requires Mass Assignment to be set up, either using the fillable or guarded properties to dictate which fields may be passed into the create call.
For this example the following would work (as a property of the User class):
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ['email', 'firstName', 'lastName'];
firstOrCreate() checks for all the arguments to be present before it finds a match.
If you only want to check on a specific field, then use firstOrCreate(['field_name' => 'value']) like:
$user = User::firstOrCreate([
'email' => 'abcd#gmail.com'
], [
'firstName' => 'abcd',
'lastName' => 'efgh',
'veristyName'=>'xyz',
]);
Then it checks only the email.
An update:
As of Laravel 5.3 doing this in a single step is possible; the firstOrCreate method now accepts an optional second array as an argument.
The first array argument is the array on which the fields/values are matched, and the second array is the additional fields to use in the creation of the model if no match is found via matching the fields/values in the first array:
See the Laravel API documentation
You can always check if in current instance the record is created with the help of
$user->wasRecentlyCreated
So basically you can
if($user->wasRecentlyCreated){
// do what you need to do here
}

Resources