I am using Laravel version 5.4 . I have a table called Users and each user has the below columns :
Schema::create('users', function (Blueprint $table) {
$defaultValue = 0;
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('facebook_id')->unique();
$table->string('avatar');
$table->integer('newsletter')->default($defaultValue); // <-
$table->bigInteger('category_1')->default($defaultValue); // <-
$table->bigInteger('category_2')->default($defaultValue); // <-
$table->bigInteger('category_3')->default($defaultValue); // <-
$table->timestamp('unlocked_tip_of_category_1_at')->nullable();
$table->timestamp('unlocked_tip_of_category_2_at')->nullable();
$table->timestamp('unlocked_tip_of_category_3_at')->nullable();
$table->rememberToken();
$table->timestamps();
});
The problem is that when i use the function to create a user category_1, category_2 and category_3 don't take the new value which is 1.
After taking auth from facebook i use the below to store user's information :
return User::create([
'name' => $facebookUser->name,
'email' => $facebookUser->email,
'facebook_id' => $facebookUser->id,
'avatar' => $facebookUser->avatar,
'newsletter' => 0,
'category_1' => 1,
'category_2' => 1,
'category_3' => 1,
]);
For example name changes to facebook user's name. Also i tried changing
'name' => $facebookUser->name,
to
'name' => $facebookUser->name . " HEY",
Which successfuly stored the name and + " HEY" at the end. (Just to be sure that this runs).
Categories are bigInteger that means a bigint(20) type. I am thinking something happens with the default values which i've set it to 0.
Any ideas? If you need any more information please let me know.
From what i am trying to accomplish the best way to solve this is to change the $defaultvalue to 1, but i don't understand why this doesn't work.
If you're using the default laravel scaffolding then you need to ensure you're updating the default App\User model based on all columns you need to have as fillable:
class User extends Model {
protected $fillable = [
'name', 'email', 'password','facebook_id','avatar','newsletter',
'category_1', 'category_2', 'category_3'
];
...
}
Same applies if you're creating your own model.
Related
I am trying to Seed a database using a Model Factory in Laravel but am seeing this error on the terminal.
$ php artisan tinker
Psy Shell v0.11.8 (PHP 8.1.0 — cli) by Justin Hileman
>>> Parking::factory(1)->create();
[!] Aliasing 'Parking' to 'App\Models\Parking' for this Tinker session.
TypeError: Illuminate\Database\Grammar::parameterize(): Argument #1 ($values) must be of type array, string given, called in C:\wamp64\www\my-valet\vendor\laravel\framework\src\Illuminate\Database\Query\Grammars\Grammar.php on line 1010
From the multiple solutions I have tried, it seems the issue is at the faker-generated content level, but I need that faker content for the factory to work as intended.
Below are the Factory and Migration classes that will help you when trying to find the solution.
Here is my factory class
class ParkingFactory extends Factory
{
protected $model = Parking::class;
/**
* Define the model's default state.
*
* #return array
*/
public function definition(): array
{
return [
'name' => $this->faker->words(2),
'description' => $this->faker->sentence,
'spaces' => rand(10, 100),
'physical_location' => $this->faker->streetAddress,
'latlng' => $this->faker->localCoordinates,
'base_pay' => $this->faker->numberBetween(100, 200),
'base_pay_breakdown' => $this->faker->sentence,
'rate_per_minute' => $this->faker->numberBetween(2, 10),
'overnight_base_pay' => $this->faker->numberBetween(100, 200),
'overnight_base_pay_breakdown' => $this->faker->sentence,
'overnight_rate_per_minute' => $this->faker->numberBetween(2, 10),
'other_charges_base_pay' => $this->faker->numberBetween(100, 200),
'other_charges_base_pay_breakdown' => $this->faker->sentence,
'other_charges_rate_per_minute' => $this->faker->numberBetween(2, 10),
'has_disability_accessibility' => $this->faker->boolean,
'has_other_charges' => $this->faker->boolean(1),
'has_overnight_parking' => $this->faker->boolean,
'overnight_charge_type' => $this->faker->randomElement(['none', 'flat', 'minute', 'both']),
// 'owner_id' => User::factory()->create(),
'created_at' => now(),
'updated_at' => now()
];
}
}
Here is the migration for the Parking table
Schema::create('parkings', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->mediumText('description');
$table->string('code')
->nullable();
$table->integer('spaces');
$table->string('physical_location')
->nullable();
$table->string('latlng')->nullable();
//charges info
$table->decimal('base_pay')
->default(0.00);
$table->string('base_pay_breakdown')
->nullable();
$table->decimal('rate_per_minute')
->default(0.00);
$table->decimal('overnight_base_pay')
->default(0.00);
$table->string('overnight_base_pay_breakdown')
->nullable();
$table->decimal('overnight_rate_per_minute')
->default(0.00);
$table->decimal('other_charges_base_pay')
->default(0.00);
$table->string('other_charges_base_pay_breakdown')
->nullable();
$table->decimal('other_charges_rate_per_minute')
->default(0.00);
//charges info end
$table->boolean('has_disability_accessibility')
->default(false);
$table->boolean('has_other_charges')
->default(false);
$table->boolean('has_overnight_parking')
->default(true);
$table->string('overnight_charge_type')
->default('none'); //flat | minute | both
$table->string('status')
->default('active');
$table->foreignId( 'owner_id')
->nullable()
->constrained('users')
->nullOnDelete();
$table->timestamps();
$table->softDeletes();
});
It is worth noting am using Laravel v9.24.0, PHP v8.1.0, and MySQL v8.0.27.
What might be the cause of my error?
The name field of your table is defined as a string, however, the words method of faker returns an array.
Supplying the words method with true as a second argument will return two words as a string.
'name' => $this->faker->words(2, true);
$this->faker->words(2)
Generates 2 words in an array, which isn't accepted as valid param when you're trying to insert it into the db.
[
"omnis",
"sequi",
]
Either serialize it using implode function, or do it any other way.
I've been trying make my validation so that an extension must be unique to it's own company but not to other companies. Here is my DB table:
$table->id();
$table->foreignId('user_id')->constrained();
$table->foreignId('account_id')->constrained()->onDelete('cascade');
$table->string('first_name')->nullable();
$table->string('last_name')->nullable();
$table->string('email');
$table->string('extension');
$table->string('password')->nullable();
$table->string('user_type')->default('user');
$table->timestamps();
$table->unique(['extension', 'account_id'], 'unique_extension');
And my validation rule looks like this:
public function rules()
{
return [
'editExtension.first_name' => 'required|max:255',
'editExtension.last_name' => 'required|max:255|',
'editExtension.email' => ['required', 'email','max:255', Rule::unique('account_users', 'email')->ignore($this->editExtension->id)],
'editExtension.extension' => ['required', 'numeric', Rule::unique('account_users', 'extension', $this->client_id)->ignore($this->editExtension->id)],
'editExtension.password' => 'required|max:255',
'editExtension.user_type' => 'required|in:user,admin',
];
}
But still I got errors saying that the extension number is already taken.
It seems that the Unique rule doesn't accept multiple columns, only one. Is this true?
How can I fix this?
Forcing A Unique Rule To Ignore A Given ID:
UPDATING AN EXISTING RECORD.
"account_users" => Table name.
"account_id", "extension" => The 2 fields to check for uniqueness.
ID of currently edited row here. => The id (primary key) to ignore. (The currently updated/edited table row id.)
Rule::unique("account_users")->where(
function ($query) use ($request) {
return $query->where(
[
["account_id", "=", $request->account_id],
["extension", "=", $request->extension]
]
);
})->ignore(/* ID of currently edited row here. */)
CREATING A NEW RECORD.
Rule::unique("account_users")->where(
function ($query) use ($request) {
return $query->where(
[
["account_id", "=", $request->account_id],
["extension", "=", $request->extension]
]
);
})
Addendum
By default, the unique rule will check the uniqueness of the column
matching the name of the attribute being validated. However, you may
pass a different column name as the second argument to the unique
method:
Rule::unique("account_users", "extension")->where(...)
I am updating my user table with validations in controller. I have created the same validation for two tables in the same controller.
When I use this code:
User::where('id',$data->user_id)->update($this->validateField($data->user_id));
it show
Error: Column not found: 1054 Unknown column 'address_name'
Which is right because user table does not have column "address_name" but its works with this code without any error
$user = User::where("id",$data->user_id)->firstOrFail();
$user->update($this->validateField($data->user_id));
What is different between these two codes, why does its not work (show unknown column Error) and why it worked without column Error?
Here is my validateField method
public function validateField($id)
{
return request()->validate([
'address_name' => 'required|string|max:255',
'mobile' => 'required|numeric|digits_between:10,13',
'land_line' => 'required|numeric|digits_between:10,13',
'min_order' => 'required',
'payment_method' => 'required',
'open_time' => 'required',
'close_time' => 'required',
'address'=>'required|string|max:255',
'city'=>'required|string|max:255',
'country'=>'required|string|max:255',
'is_active' => 'required',
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'email' => 'required|email|max:255|unique:users,email,'.$id.',id,deleted,0',
'password' => 'sometimes|required|min:8',
]);
}
my user table
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('first_name');
$table->string('last_name');
$table->string('email');
$table->string('password');
$table->string('mobile');
$table->tinyInteger('user_role')->unsigned();
$table->tinyInteger('is_active')->unsigned()->default(1);
$table->datetime('last_login')->nullable();
$table->tinyInteger('deleted')->unsigned()->default(0);
$table->dateTime('created_at')->nullable();
$table->dateTime('updated_at')->nullable();
$table->integer('updated_by')->nullable();
$table->rememberToken();
});
Well
User::where('id',$data->user_id)->update($this->validateField($data->user_id));
this will update all the records that correspond to the where with the fields passed as parameter to the update function, it's just a case that the where will have just one match (because you are applying the where clause to the primary key), if there were more than one match, all the records will be update.
Keep in mind that the where function will return a Builder, and so the update function is the update of the class Builder: it means that there will be only one query (update ... set ... where id = /*your id*/).
This instead
User::where("id",$data->user_id)->firstOrFail()->update($this->validateField($data->user_id))
will first get the first Record that match the where clause, so there will be a Query like select .. from .. where id= /*your id*/, than on that Model will be called the update function, so the function invoked here id the Model -> update function, where previously was Builder -> update, and so there will be a second query with the update.
The different behavior is caused by the different implementation of the update function in the two classes. Actually, on my server, both the methods will throw an error if some fields inside the array passed to update aren't table fields, don't know why on your the first one works fine
Please help me for developing a website? I want to fetch data from the cycles table so that I can make a if condition and make a relationship to moralities table.
The cycles table has the following data:
$table->increments('id');
$table->date('date_start_raise');
$table->integer('population');
$table->integer('raising_days');
$table->date('date_end_raise');
$table->date('date_manure_collection');
$table->date('date_cleaning');
$table->date('date_disinfection');
$table->date('date_rest_day');
$table->date('date_preparation');
$table->unsignedInteger('user_id');
$table->timestamps();
The data that I need are date_start_raise, date_end_raise, and id
The mortalities table has the following data:
$table->increments('id');
$table->date('date_input');
$table->integer('number_of_mortality');
$table->integer('chicken_age');
$table->mediumText('cause_of_death')->nullable();
$table->unsignedInteger('cycle_id');
$table->unsignedInteger('user_id');
$table->timestamps();
I need to pass id(cycle) to cycle_id(mortalities).
Before that, I need to make a condition so that the content of mortalities will arrange accordingly by cycle_id and it will make a relationship to the cycles table
The data will be use are date_input(mortalities), date_start_raise, and date_end_raise(cycle).If data_input belongs to the date range from date_start_raise to date_end_raise, the id will be pass to cycle_id.
For Example
There are two data in cycles table
(September 3 - 28): id = 1 (October 1 - November 5): id= 2
The user opens the mortality modal to input data and send data to mortalities table.
According to mortality modal, the date(date_input) is September 6. The id will be be fetch is 1 because the date_input belongs of date range(from date_start_raise to date_end_raise) September 3 - September 28 and the cycle data’s id is 1. After fetching, the value of id will pass to cycle_id(mortality) so that the two tables have relationship.
I try this code but it was an error
"message": "Call to undefined method App\Cycle::date_start_raise()",
MortalityController.php (store)
public function store(Request $request)
{
$cycle_id = Mortality::whereDate([
['date_input','>=', Cycle::date_start_raise()],
['date_input','<=', Cycle::date_end_raise()],
])->get(Cycle::id());
$this->validate($request, array(
'date_input' => 'required|date',
'number_of_mortality' => 'required|numeric',
'chicken_age' => 'required|numeric'
));
return Mortality::create([
'date_input' => request('date_input'),
'number_of_mortality' => request('number_of_mortality'),
'chicken_age' => request('chicken_age'),
'cause_of_death' => request('cause_of_death'),
'cycle_id' => $cycle_id,
'user_id' => Auth::id()
]);
}
Please help me. Thanks in advance :)
You are calling data_start_raise() without actually telling it what entry to do it on
['date_input','>=', Cycle::date_start_raise()],
['date_input','<=', Cycle::date_end_raise()
You would have to find an entry for example
Cycle::find( id goes here )->date_start_raise()
https://laravel.com/docs/5.7/eloquent
public function store(Request $request)
{
$cycle = Mortality::whereDate([
[request('date_input'),'>=', Cycle::date_start_raise()],
[request('date_input'),'<=', Cycle::date_end_raise()],
])->get()->first();
if ($cycle!==NULL)
{ $cycle_id = $cycle->id;}
else return;//you may send with an error message like invalid date
//above lines are a little bit changed.
$this->validate($request, array(
'date_input' => 'required|date',
'number_of_mortality' => 'required|numeric',
'chicken_age' => 'required|numeric'
));
return Mortality::create([
'date_input' => request('date_input'),
'number_of_mortality' => request('number_of_mortality'),
'chicken_age' => request('chicken_age'),
'cause_of_death' => request('cause_of_death'),
'cycle_id' => $cycle_id,
'user_id' => Auth::id()
]);
}
When you used get method with where clause, you were getting a collection; not a single instance. That is why you couldn't assign the id. By using first(), we are getting a single id.
as In laravel we Use Migrations to Create Tables and then Seeders to seed out table, am not getting its benefit, as we can do that in normal way by just going to PHPMYADMIN then what we need to that, as we code many lines for it, but how can we justify those lines of code ?
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateItemsTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('items', function(Blueprint $table)
{
$table->increments('id');
$table->integer('owner_id');
$table->string('name');
$table->boolean('done');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('items');
}
}
it is true that migrations are being created by php artisan commands, But what is the benefit of them? as we have an alternate to do that?
same for the Seeder files as we code many lines for it
class ItemTableSeeder extends Seeder{
public function run(){
DB::table('items')->delete();
$items= array(
array(
'owner_id' => '1',
'name' => 'Watch The Spectacular Now',
'done' => True
),
array(
'owner_id' => '2',
'name' => 'Watch Avengers',
'done' => False
),
array(
'owner_id' => '1',
'name' => 'Watch The Iron man',
'done' => False
),
array(
'owner_id' => '1',
'name' => 'Divergent',
'done' => False
),
array(
'owner_id' => '1',
'name' => 'Bat Man',
'done' => False
),
array(
'owner_id' => '1',
'name' => 'X-Men Days Of Future Past',
'done' => False
)
);
DB::table('items')->insert($items);
}
}
The main benefit is that you will do it in your development server/station, and you may change the schema many times in development, migrate, rollback migrations, and re-migrate them, and as soon as your application id done, you don't have to remember what you have to do in your production environment, Laravel will do it automatically for you.
Using PHPMyAdmin, you would have to create tables and edit fields manually locally and in your remote server, and you would risk forgetting something and breaking your application. And, if you have more than one server serving your application, the problem is bigger.
Migrations and seeds are database versioning. Imagine that one day you fall in love with, say PostgreSQL or anything other than MySQL. Then imagine you'd like to do some tests with more than several rows of data.. Would you run PHPMYADMIN's equivalent and insert 100, 1000 or 10000 rows?
So now check this out:
// migration
class CreateCommentsTable extends Migration {
public function up()
{
Schema::create('comments', function(Blueprint $table) {
$table->increments('id');
$table->string('body');
$table->integer('author_id')->unsigned();
$table->integer('post_id')->unsigned();
$table->timestamps();
});
}
// seeder
class CommentsTableSeeder extends Seeder {
public function run()
{
Eloquent::unguard();
$faker = Faker::create();
foreach(range(1, 1000) as $index)
{
Comment::create([
'body' => $faker->sentence(10),
'author_id' => rand(1,20),
'post_id' => rand(1,150)
]);
}
}
Faker is a great tool you can find here: https://github.com/fzaninotto/Faker
All you need to do now is run artisan migrate --seed.
Of course there are more advantages than automating seeds, you can alter your tables with migrations in case you want to change your schema and so on.
Migration files maintains the schema of the tables. Using migration, you may never have to go to phpMyAdmin (except for creating a DB). Once done you can simply run the command 'php artisan migrate' and create the tables from the PHP side itself. Also you will never have to worry about the DB environment (MySql, Posgres, Sql Lite etc) as the migration does not truly depend on the environment to which you are migrating the tables.
Seeding helps in creating, for example, different roles (Admin, User, Editor etc) within your application. You will have to just create the seeder files and run the 'php artisan db:seed' command to populate data to the tables from the php side. Also seeds help in creating test data.