Model:create used once but two rows created (laravel) - laravel

I was coding in my app and suddenly I realized that every create in my app makes two rows!
whenever I run model:create it makes two rows! it doesn't matter how or when I use a create method.
For example:
Route::get('test', function () {
\App\City::create([
'name' => 123,
'province_id' => 1
]);
});
obviously such code should create one row. but it creates two! I am stuck and don't know what to do!!
Update:
the city model is simple, but it doesn't matter what model I use.
But, running same code during interactive php artisan tinker session creates one row.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class City extends Model
{
public $timestamps = false;
protected $fillable = ['name' , 'province_id'];
public function province()
{
return $this->belongsTo('App\Province');
}
}

Related

Show function not working. Can't retrieve element by id. Laravel 5.8

I have created resource controllers, one per model in my laravel 5.8 project. I want the show function to return the DB element i want based on the id inserted on the URL, as it is supposed to do. For now i do tests directly on my controller, i'm not using the "thisCircuit" function of my model. Calling the index, returns a json with all circuits. Calling the show returns nothing. How can i fix it?
Show function
public function show(circuits $circuits)
{
$circuits = circuits::findOrFail($circuits);
dd($circuits);
}
Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class circuits extends Model
{
protected $fillable = [
'circuitId', 'circuitRef', 'name',
'location', 'country', 'lat',
'lng', 'alt', 'url',
];
protected $primaryKey = 'circuitId';
public function races()
{
return $this->hasMany('App\races', 'circuitId');
}
public function allCircuits(){
$data = Circuits::all();
return response()->json($data);
}
public function thisCircuit($id){
$id = circuits::findOrFail($id);
}
}
Web.php File
Route::get('/test', 'CircuitsController#index');
Route::get('/test/{circuit}', 'CircuitsController#show');
URL on browser
http://localhost:8000/test/1
Result on browser
Illuminate\Database\Eloquent\Collection {#947 ▼
#items: []
}
Ok, let's clean up this solution. A lot of smaller stylistic problems, that will hurt you going forward if not adjusted.
Firstly
Class names are starting with capitols letter in most standard naming conventions and in singular form.
circuits.php
Should be.
Circuit.php
Secondly
You are already using model binding. If you are doing this approach you can actually just return the circuit directly. As a bonus Laravel does not have to return response if the returned data is a model, unless you want to change the response code from 200 to something else.
public function show(Circuit $circuit) {
return $circuit;
}
Also you are misunderstanding firstOrFail(). This code you have written can never return multiple Circuits, this will return a singular model.
$circuits = circuits::findOrFail($circuits);

error when attempting to seed pivot table using Laravel

I have just created a many-to-many relationship between the models Project and Features using Laravel however I receive the following error when attempting to run the seed script.
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'table.feature_projects' doesn't exist
The table in use is named features_project which is the default name given.
Inserting the seed data manually does return the relational data to the view as expected.
SEED
class FeaturesProjectTableSeeder extends Seeder
{
public function run()
{
$features_project = new \App\FeatureProject ([
'project_id' => '1',
'features_id' => '1'
]);
$features_project->save();
}
}
Project
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Project extends Model {
public function features() {
return $this->belongsToMany('App\Features')->withTimestamps();
}
}
Features
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Features extends Model
{
public function projects() {
return $this->belongsToMany('App\Project')->withTimestamps();
}
}
CONTROLLER
class ProjectController extends Controller
{
public function getProject($id)
{
$project = Project::where('id', $id)->get();
return view('other.project', ['project' => $project]);
}
}
ROUTE
Route::get('project/{id}', [
'uses' => 'ProjectController#getProject',
'as' => 'other.project'
]);
VIEWS
#foreach($project->features as $feature)
<dd class="col-sm-8">{{ $feature->name }}</dd>
#endforeach
Firstly some misunderstanding in naming, your table name should be feature_project, in many to many relationships the models are in alphabetical order. Secondly models are not plural, so your Features.php model should be named Feature.php. Which will resolve in Laravel using the table feature_project for the pivot and features for the model.
For your own sake, learn how Laravel name models and tables, else relationships are gonna be tricky. Which is described in the documentation.
You should not create pivot models, this is handled by assigning features to projects or vice versa. Therefor your seeder should look something like this, it could be you should assign some attributes to the projects and features before it will work.
class FeaturesProjectTableSeeder extends Seeder
{
public function run()
{
$features = factory(Feature::class)->create();
$projects = factory(Project::class)->create();
$projects->each(function (Project $project) {
$project->features()->saveMany($features);
});
}
}

Laravel update different database table

I have a controller in Laravel that is adding a 'room' to the database, like this...
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Room;
class SitesController extends Controller
{
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required',
]);
/* Create Post */
$room = new Room;
$room->name = $request->input('name');
$room->save();
return redirect('/room')->with('success', 'Room Created');
}
}
This works great but I would also like to write something to a different database table. Am I locked in to only updating the 'rooms' table in this controller or is there a way to modify others?
You are asking
to write something to a different database table,
not into a totally different database, right?
Why would you think you are locked in? Just use another Model that represents the table you want to update as well.
use App\YourOtherModel;
...
/* Create Post */
$room = new Room;
$room->name = $request->input('name');
$room->save();
$other = new YourOtherModel;
... go ahead
$other->save();

Simple Laravel Relationship

I have two models, one is LeadHistory and the other one is Leads.
Leads:
class Leads extends Model
{
public function lead_history()
{
return $this->hasMany('App\LeadHistory');
}
}
LeadHistory:
class LeadHistory extends Model
{
public function lead()
{
return $this->belongsTo('App\Leads', 'lead_id', 'id');
}
}
When I go into php tinker, get the first Lead ($lead = App\Leads::first();), create a new LeadHistory ($leadHistory = new App\LeadHistory;) and ($leadHistory->message = 'second one';) and ($leadHistory->status_id = 11;) then try to save the leadHistory ($leadHistory->lead()->save($lead);). I get this error message:
BadMethodCallException with message 'Call to undefined method Illuminate\Database\Query\Builder::save()'
Can someone point me in the right direction, I feel like I have been following the instructions given in Laracasts but can't seem to get the LeadHistory to save with the associated Lead ID.
You’re trying to call save() on a relation rather than a model I think.
Instead, “attach” your LeadHistory model to your Lead model:
$lead = Lead::create($leadAttributes);
$history = new LeadHistory($leadHistoryAttributes);
$lead->history()->attach($history);
You’ll need to rename your relation if you copy-and-paste the above code:
class Lead extends Model
{
public function history()
{
return $this->hasMany(LeadHistory::class);
}
}
I feel the name “lead history” is superfluous when you’re already working with a Lead model.
Try to save $leadHistory first:
$leadHistory->save();
And then:
$lead->lead_history()->save($leadHistory)
Correct me if I'm wrong, but since you already have a model instance of your target App\Leads, I think you should be able to simply access the id of that instance and inject it into a static create call:
$lead = App\Leads::first();
$leadHistory = App\LeadHistory::create([
'message' => 'second one',
'status_id' => 11,
'lead_id' => $lead->id
]);
Before being able to use the create method you'd have to make the properties you want to assign 'mass assignable', by defining a protected property called $fillable in your model:
class LeadHistory extends Model
{
protected $fillable = [
'message',
'status_id',
'lead_id'
];
public function lead()
{
return $this->belongsTo('App\Leads', 'lead_id', 'id');
}
}
This will effectively associate your new record with that lead, since the only thing the Eloquent model does in this regard is providing another way to describe the same relationships your database exercises.
Some other answers mention the attach() method of an Eloquent model. This method is used to attach two models with a many to many relationship (relationships defined with belongsToMany).

Laravel 5 Seeding Pivot Tables

I was watching the following lesson and was following along with Roles and Permissions however now I"m to seeding my pivot table with a Seeder class but not sure how I should accomplish this.
https://laracasts.com/series/whats-new-in-laravel-5-1/episodes/16
This is the sort of thing I have right now but obviously with the givePermissionTo() inside of the Role model I'm sure there is a better way of handling this. I have a feeling I don't even need a PermissionRole model. The big issue here is that I run it for all 5 different roles and about 63 different permissions.
<?php
use Illuminate\Database\Seeder;
use App\PermissionRole;
class PermissionRoleTableSeeder extends Seeder
{
public function run()
{
PermissionRole::create([
'role_id' => 5,
'permission_id' => '1',
]);
PermissionRole::create([
'role_id' => 5,
'permission_id' => '2',
]);
PermissionRole::create([
'role_id' => 5,
'permission_id' => '3',
]);
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
public function permissions()
{
return $this->belongsToMany(Permission::class);
}
public function givePermissionTo(Permission $permission)
{
return $this->permissions()->save();
}
public function users()
{
return $this->hasMany(User::class);
}
}
Can someone hint as to what that is?
You usually shouldn't have a model for your pivot table, although there are times when it makes sense to have it in the event you have an additional key in the pivot table which points to a table which isn't part of the belongs to many relationship. For example, if you had a created_by field in your pivot table which would be the id of the user which created that relation.
With that said, it also should not hurt anything to have a model for your pivot table to help you work with it directly like you are doing.
To see the table without the model, I'd use the Laravel functions provided. I don't know how that givePermissionTo function is supposed to work because you aren't actually using the argument provided.
I'd put some constraints on this, but one way you could do it would be to use the sync function. This will give all roles all permissions.
$roles = \App\Role::all();
$permissions = \App\Permission::all();
foreach($roles as $role) {
$role->permissions()->sync($permissions);
}

Resources