I have a table called agency_persons with some data already in it. I created a model using php artisan:
php artisan make:model AgencyPerson
Now when I try to use Laravel's Eloquent methods i face following error:
Base table or view not found: 1146 Table
'my_database.agency_people' doesn't
Laravel is looking for people table instead of persons.
I know Laravel is trying to do the right thing and I should have named my table agency_people in the first place, but I cannot change name of the table, because other applications are using this table too.
How can I disable laravel's pluralization for person to people?
In the model, add the line
protected $table = 'agency_persons';
See https://laravel.com/docs/5.5/eloquent for more details, look for section Tablenames
If you are using persons table and person model in laravel. Laravel Pluralization For Person To People will give you this error whatever your query would be:-
Base table or view not found: 1146 Table 'lrv_db.people' doesn't exist (SQL: select `posts`.*, `people`.`country_id` from `posts` inner join `people` on `people`.`id` = `posts`.`person_id` where `people`.`country_id` = 1)'
Solution for this is :-
Define your table in the person model as below:
class person extends Model
{
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'persons';
}
You can also define which model attributes you want to make mass assignable. You may do this using the $fillable property on the model.
Example:
protected $fillable = ['title', 'description'];
Once you have made the attributes mass assignable, you can use the create method to insert a new record in the database.
The use of $fillable to protect which fields you want this to actually allow for updating.
Related
I am curious about how eloquent knows in which table it should save the records we give it by running $ php artisan tinker . I do not actually remember setting so an option.
In Laravel when using Eloquent you should assign a table name using the property $table for example:
protected $table = 'some_thing';
Otherwise it assumes that the table name is the plural form of the model name and in this case for User model the table name should be users. Follwing paragraph is taken from Laravel website:
Table Names
Note that we did not tell Eloquent which table to use for our Flight
model. The "snake case", plural name of the class will be used as the
table name unless another name is explicitly specified. So, in this
case, Eloquent will assume the Flight model stores records in the
flights table.
// You may use this instead:
class Flight extends Model
{
// Explicit table name example
protected $table = 'my_flights';
}
So, if you don't follw this convention when creating/naming your database tables that Laravel expects then you have to tell Laravel the name of the table for a model using a protected $table property in your model.
Read the documentation here.
Actually if you not set the $table property, Eloquent will automatically look the snake case and plural name of the class name. For example if class name is User, it will users.
Here the code taken from Illuminate/Database/Eloquent/Model.php
public function getTable()
{
if (isset($this->table)) {
return $this->table;
}
return str_replace('\\', '', Str::snake(Str::plural(class_basename($this))));
}
Model name is mapped to the plural of table name, like User model maps to users table and so.
When you do
User::all() laravel knows that you want the records from users table.
To specify the table name explicitly you use protected $table ='name' field on model.
Actually, Eloquent in its default way, is an Active Record System just like Ruby On Rails has. Here Eloquent is extended by a model. Those model name can be anything starts with capital letter. Like for example User or Stock
but the funny thing is this active record system will imagine that if no other name of custom table is specified within the class model then the table name should be the small cased plural form of the Model name. In these cases users and stocks.
But by keeping aside theses names you can extensively can provide your own table name within the model. As in Laravel protected $table= 'customTableName'
Or, in a more descriptive way,
class Stock extends Eloquent{
// Custom Table Name
protected $table = 'custom_tables';
}
I hope this will solve your curious mind.
I just recently started experimenting with laravel, lovely. One thing l dont understand though is how laravel knows my table l just added a model and the model isnt the exact table name, but just how does it manage to get my table,
Reference to Eloquent Model Conventions:
Note that we did not tell Eloquent which table to use for our Flight
model. By convention, the "snake case", plural name of the class will
be used as the table name unless another name is explicitly specified.
Internally, Laravel does something like this.
$table = $table ?: Str::plural($name);
So it will automatically try to look for the plural of your model name if no $table property is being set.
Laravel follows a Naming convention for Eloquent Classes and Tables.
From Laravel Website | Eloquent: Getting Started
Note that we did not tell Eloquent which table to use for our Flight
model. By convention, the "snake case", plural name of the class will
be used as the table name unless another name is explicitly specified.
So, in this case, Eloquent will assume the Flight model stores records
in the flights table.
Eg.
Class User will by default refers to Mysql Table users (Camel Case to Snake Case and Plural).
Class NotificationsLog will by default refers to Mysql Table notifications_logs (Camel Case to Snake Case and Plural).
But if you don't want to follow the convention then you can Mention the table name explicitly
Eg.
If I want my Class Plane should refers to flights table in Database then following code will work
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Plane extends Model
{
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'flights';
}
Actually the when you make a model it automatically make a table with it's plural you could change this by added the following code in the model
protected $table= 'table_name';
Please also check the name in the migration it should be same as the name you mentioned in the model class because it might show error while using eloquent class functions due to different table names
My Laravel User Table name is s_user but result is:
SQLSTATE[42S02]: Base table or view not found: 1146 Table
'laravel_learn.users' doesn't exist (SQL: select * from users where
users.id = 1 limit 1) (View:
C:\xampp\htdocs\nawabpur1\resources\views\frontend.blade.php)
Please help me! how can i change users table. my table name is s_user but laravel query result show users but why? how can i change it users to s_user?
Since you have not defined that what the table name is, Eloquent automatically, searches for snake cased plural form of your model's name, in this case users, furthermore, as it can not locate it, you get that error.
So to edit it, within the app\User.php file, which is your User model, set the $table property.
For your other question, which you have posted as an answer as how to change the primary key field, Eloquent assumes you have an primary column named as id, to change it, set it within the $primaryKey variable.
class User extends Model
{
// Define table name explicitly
protected $table = 's_user';
// Define primary key explicitly
protected $primaryKey = 'user_id';
}
All of those information are written in the Laravel documentation, do not forget it, check it out.
I just used Artisan CLI to make a migration for a model called story:
php artisan make:model Story
And it created a migration file that creates a table called stories and not storys. Even though it is grammatically correct, it makes me wonder what other non-conventional corrections it can make. In other words, what are rules that CLI follows to create a migration file? Also, do these "correct" names apply to column names or not? Will the migration table for a polymorphic tags table be taggable_id or tagable_id? Bear in mind that Eloquent doesn't expect a taggable_id by default.
here is exactly your question you can find out why in this link .
https://laracasts.com/discuss/channels/general-discussion/makemodel-also-creates-a-migration
Laravel follows simple naming convention. table name should be plural to the model name. But if you want to specify the table name you add this property in the model
protected $table = 'myclients'
According to this Eloquent has its own conventions. For example a Travel model retrieve and store information from our travels database table.
But the important point is that Laravel Migration doesn't force us to choose table name that it wants!
The "snake case", plural name of the class will be used as the table
name unless another name is explicitly specified.
So , U can easily change the name of referenced table to whatever u want.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Travel extends Model
{
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'whatever_you_want';
}
When I went through Laravel Document about Eloquent ORM topic part, I got a new term "Mass Assignment".
Document show How to do Mass Assignment and the $fillable or $guarded properties settings. But after went through that, I didn't have a clearly understand about "Mass Assignment" and how it works.
In my past experience in CodeIgniter, I also didn't hear about this term.
Does anyone have a simple explanation about that?
Mass assignment is when you send an array to the model creation, basically setting a bunch of fields on the model in a single go, rather than one by one, something like:
$user = new User(request()->all());
(This is instead of explicitly setting each value on the model separately.)
You can use fillable to protect which fields you want this to actually allow for updating.
You can also block all fields from being mass-assignable by doing this:
protected $guarded = ['*'];
Let's say in your user table you have a field that is user_type and that can have values of user / admin
Obviously, you don't want users to be able to update this value. In theory, if you used the above code, someone could inject into a form a new field for user_type and send 'admin' along with the other form data, and easily switch their account to an admin account... bad news.
By adding:
$fillable = ['name', 'password', 'email'];
You are ensuring that only those values can be updated using mass assignment
To be able to update the user_type value, you need to explicitly set it on the model and save it, like this:
$user->user_type = 'admin';
$user->save();
Mass assignment is a process of sending an array of data that will be saved to the specified model at once. In general, you don’t need to save data on your model on one by one basis, but rather in a single process.
Mass assignment is good, but there are certain security problems behind it. What if someone passes a value to the model and without protection they can definitely modify all fields including the ID. That’s not good.
Let's say you have 'students' table, with fields "student_type, first_name, last_name”. You may want to mass assign "first_name, last_name" but you want to protect student_type from being directly changed. That’s where fillable and guarded take place.
Fillable lets you specify which fields are mass-assignable in your model, you can do it by adding the special variable $fillable to the model. So in the model:
class Student extends Model {
protected $fillable = ['first_name', 'last_name']; //only the field names inside the array can be mass-assign
}
the 'student_type' are not included, which means they are exempted.
Guarded is the reverse of fillable. If fillable specifies which fields to be mass assigned, guarded specifies which fields are not mass assignable. So in the model:
class Student extends Model {
protected $guarded = ['student_type']; //the field name inside the array is not mass-assignable
}
you should use either $fillable or $guarded - not both.
For more details open link:- Mass Assignment
Mass assignment means you are filling a row with more than one column using an array of data. (somewhat of a shortcut instead of manually building the array) using Input::all().
Technically just from the top of my head. Fillable means what columns in the table are allowed to be inserted, guarded means the model can't insert to that particular column.
Notice that when you try to do a mass assignment with like, insert to a column named "secret", and you have specified that it is guarded, you can try to insert to it via the model, but it will never really get inserted into the database.
This is for security, and protection on your table when using the model. Mass assignment seems to be just a notice or warning that you didn't tell the model which are fillable and guarded and makes it vulnerable to some kind of attacks.
This is when an array of data received is saved at once in a model.
Because of the security issues with this method in laravel, it's recommended you define the fields you wish the requested data to populate on the Model.
You can use the $fillable variable to define the fields you want to populate on the database table.
E.g
Protected $fillable = [‘username’, ‘dob’, ‘email’,];
When laravel detects you are mass assigning data, it forces you to define the fields you want to mass assign in the model class.
Someone can easily pass unwanted data into an html form to your database.
There are two ways to handle this.
Laravel Eloquent provides an easy way to achieve this.
In your model class, add $fillable property and
specify names of columns in the array like below:
You can achieve this by adding $guarded property in model class:
You can either choose $fillable or $guarded but not both.