How to store data in Laravel - laravel

I try to store data to DB.
Following your recommendations, I created a schema
Schema::create('user_info', function (Blueprint $table) {
$table->string('name')->index();
$table->string('ip');
$table->timestamp('created_at')->nullable();
});
I created a model for a UserInfo where I plan to store IP and name
class UserInfo extends Model
{
protected $fillable = ['ip'];
}
In HomeController
public function store(Request $request) {
$user_info = new UserInfo;
$user_info->ip = $request->ip;
$user_info->name = $request->name;
$user_info->save();
}
UserInfo::create(['user_info' => Request::user_info()]);
As a result, I've got the below-given error
Method Illuminate\Http\Request::user_info does not exist.

Look there are several issues. Firstly in Schema consider using an incremental id as the primary key.
Add name in the fillable property.
protected $fillable = ['name','ip'];
And finally in the controller either use one procedure to save to the database.
public function store(Request $request) {
$user_info = new UserInfo;
$user_info->ip = $request->ip;
$user_info->name = $request->name;
$user_info->save();
}
Or
public function store(Request $request) {
UserInfo::create([
'name' => $request->name,
'ip' => $request->ip
]);
}

Request is a class. Instead, use the $request variable provided as an argument in your function:
UserInfo::create(['user_info' => $request->input('user_info')]);

Related

laravel 8 store request with foreign key user_id not working

I would like to store the corresponding logged in user when adding a new School data. What I'm trying to do is store the logged in user_id in the schools table, in order to know on who added the school data. I have a users table already, which will establish the relation in the schools table.
My goal is when an admin is logged in, he/she can see all of the School records, otherwise if it's a user, then only fetch the records he/she added. The problem is that I can't figure out on when and where to insert the user_id data during the store request as I'm getting an error "user id field is required". Here's what I've tried so far:
Migration:
class CreateSchoolsTable extends Migration
{
public function up()
{
Schema::create('schools', function (Blueprint $table) {
$table->id();
$table->string('school_name');
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->timestamps();
});
}
}
School Model:
class School extends Model
{
use HasFactory;
protected $fillable = ['school_name', 'user_id'];
public function User() {
return $this->belongsTo(User::class);
}
}
Store Request:
class StoreSchoolRequest extends FormRequest
{
public function rules(): array
{
return [
'school_name' => 'required|string|max:255',
'user_id' => 'required|exists:users,id'
];
}
}
Controller:
class SchoolController extends Controller
{
public function store(StoreSchoolRequest $request) {
$school_data = $request->validated();
$user_id = \Auth::user()->id;
$school_data['user_id'] = $user_id;
School::create($school_data );
return Redirect::route('schools.index');
}
}
Any inputs will be of big help! Thanks.
Laravel has elegant way to bind authenticated user_id. Remove user_id from request class and chaining method. Also setup relationship from User model to School Model
Form Request Class
class StoreSchoolRequest extends FormRequest
{
public function rules(): array
{
return [
'school_name' => 'required|string|max:255',
];
}
}
User Model
protected $fillable = ['school_name', 'user_id'];
...
// new line
public function schools() {
return $this->hasMany(School::class);
}
Your Controller
class SchoolController extends Controller
{
public function store(StoreSchoolRequest $request) {
auth()->user()->schools()->create($request->validated());
return Redirect::route('schools.index');
}
}
UPDATE ANSWER
Since user_id value is school name (based on image link from comment), probably there's something wrong either in User or School model. Here the quick fix
Your Controller
class SchoolController extends Controller
{
public function store(StoreSchoolRequest $request) {
auth()->user()->schools()->create(
array_merge(
$request->validated(),
['user_id' => auth()->id()]
)
);
return Redirect::route('schools.index');
}
}
You can add 'created_by' and 'updated_by' fields to your table. so you can register in these fields when additions or updates are made.
Then you can see who has added or updated from these fields.
class School extends Model
{
use HasFactory;
protected $fillable = ['school_name', 'user_id', 'created_by', 'updated_by'];
public function User() {
return $this->belongsTo(User::class);
}
}
Your controller part is correct but since you get the logged in user, you wont be having user_id in the request. So you should remove the rules about user_id from your StoreSchoolRequest.
class StoreSchoolRequest extends FormRequest
{
public function rules(): array
{
return [
'school_name' => 'required|string|max:255'
];
}
}
Problem is here ..
$school_data = $request->validated();
Since you are using $request->validated()..
You have to safe()->merge user_id into it , here Docs : .
$validated = $request->safe()->merge(['user_id' => Auth::user()->id]);
Then put this $validated into create query , Thanks. –

Laravel how to save belongstomany in store controller?

I can save my ticket inside a ticket table. But i also have a ticket_user table with inside a ticket_id and a user_id. So when the user press save it need to automaticlay pick also the ticket_id and the user_id inside the ticket_user table. I have a many to many table between Users and Ticket.
this is the error i get Call to a member function attach() on null
User Models
public function ticket(){
return $this->belongsToMany(Ticket::class, 'ticket_user');
}
Ticket models
public function users() {
$this->belongsToMany(User::class, 'ticket_user');
}
Controller
public function store(Request $request)
{
$this->validate($request, array(
'title' => 'required',
'ticket' => 'required'
));
$ticket = new Ticket;
$ticket->title = $request->title;
$ticket->ticket = $request->ticket;
$ticket->save();
$ticket->users()->attach($request->input('user_id'));
return redirect()->route('users.tickets.index');
}
You are not returning anything in users function in Ticket class.
public function users() {
return $this->belongsToMany(User::class, 'ticket_user');
}

Update fields from two tables in Laravel

I have 2 models: customer and customerName. In my customer Controller I try to create a method that update fields from both tables. Any idea? Thanks!
CustomerController
public function update(Request $request, Customer $customer)
{
$customer = \App\CustomerName::where('customer_id', $customer->id)->first(); // if I remove this line I can update just "name" from first table
$data = $request->validate([
'name' => 'required|string', //is in customer migration
'first_name'=> 'required', //is in customerName migration
'last_name'=> 'required', //is in customerName migration
]);
$customer->update($data);
return response($customer,200);
}
Customer Model
class Customer extends Model
{
protected $fillable = ['name'];
public function customerName()
{
return $this->hasOne('App\CustomerName');
}
}
CustomerName Model
class CustomerName extends Model
{
protected $fillable = ['first_name', 'last_name'];
public function customer()
{
return $this->belongsTo('App\Customer');
}
}
Assuming customer always has record created for CustomerName, you should then use:
$customer->update(['name' => $data['name']);
$customer->customerName->update(\Arr::only($data, ['first_name', 'last_name']));
and additionally you should wrap this in database transaction like so:
\DB::transaction(function() use ($customer, $data) {
$customer->update(['name' => $data['name']);
$customer->customerName->update(\Arr::only($data, ['first_name', 'last_name']));
});
and of course you should remove this line:
$customer = \App\CustomerName::where('customer_id', $customer->id)->first(); // if I remove this line I can update just "name" from first table
because you should already have $customer object set using Route model binding.
Take a look at your code. You're overriding some variables by naming them the same thing:
public function update(Request $request, Customer $customer)
{
$customer = \App\CustomerName::where('customer_id', $customer->id)->first();
...
Before the line $customer = \App\CustomerName..., $customer is an instance of Customer. After that line, it is an instance of CustomerName, and you no longer have access to the Customer instance. Simply change you naming:
public function update(Request $request, Customer $customer)
{
$customerName = \App\CustomerName::where('customer_id', $customer->id)->first();
// Or, $customerName = $customer->customerName;
// You shouldn't have to query if your relationship is defined properly.
...
Next, save the values accordingly:
$customer->name = $request->input("name"); // or $data["name"]
$customer->save();
$customerName->first_name = $request->input("first_name"); // or $data["first_name"]
$customerName->last_name = $request->input("last_name"); // or $data["last_name"]
$customerName->save();
Set the values of $customer and $customerName accordingly, then call save() on both instances.
You're injecting the Customer instance, so you don't need to load it inside the function. Try this:
public function update(Request $request, Customer $customer)
{
$data = $request->validate([
'name' => 'required|string', //is in customer migration
'first_name'=> 'required', //is in customerName migration
'last_name'=> 'required', //is in customerName migration
]);
$customer->name = $data['name'];
$customer->customerName->first_name = $data['first_name'];
$customer->customerName->last_name = $data['last_name'];
$customer->push(); // This saves the model AND the related models as well.
return response($customer,200);
}

Passing data from controller into Model in Laravel

I have this comment controller:
class CommentsController extends Controller
{
public function store(Article $article){
$comment = new Comment();
$comment->user_id = auth()->id();
$comment->comment = request('comment');
$comment->article_id = $article->id;
$comment->save();
return back();
}
}
And it works. I tried to make my code cleaner by putting that logic into my model. So I changed it like this:
class CommentsController extends Controller
{
public function store(Article $article){
$article->addComment(request('comment'));
return back();
}
}
Meanwhile, in my Comment Model I'm doing like this:
class Article extends Model
{
protected $fillable = ['title','content','user_id'];
public function comments(){
return $this->hasMany(Comment::class);
}
public function user(){
return $this->belongsTo(User::class);
}
public function addComment($comment){
Comment::create([
'comment' => $comment,
'article_id' => $this->id,
'user_id' => auth()->id()
]);
}
}
but when I do this, I'm getting this kind of error:
"SQLSTATE[HY000]: General error: 1364 Field 'user_id' doesn't have a default value (SQL: insert into `comments` (`comment`, `article_id`, `updated_at`, `created_at`) values (Test comment bla bla bla..., 1, 2017-10-16 09:27:27, 2017-10-16 09:27:27)) ◀"
It seems I can't get the user_id in that manner, so how can I pass the user id so i can insert it into my comment tables? Thanks.
You need to add user_id to $fillable array in Comment model, not in Article model to make it work. Your original code works just because you do not use mass assignment there.
Try this:
public function addComment($comment){
Comment::create([
'comment' => $comment,
'article_id' => $this->id,
'user_id' => \Auth::user()->id
]);
}
try
\Auth::id()
instead of
auth()->id()
and go to your database and and make user_id default as NULL
The reason for this kind of error is that laravel protects database fields for mass assignment when you add the following code it makes all fields fillable.
protected $guarded = [];
Another way of doing is to add user_id in comments model. Is this case it will only allow the fields mentioned in the array to be mass assigned.
protected $fillable = [
'user_id'
];

Relationship hasone trying to get property of non-object

I got a problem with relationship one to one mechanism for edit & update condition, so I have model Siswa and Telepon, with Telepon belongs to Siswa... here is the code
Siswa.php (model)
class Siswa extends Model
{
protected $table = 'siswa';
protected $fillable = [
'nisn',
'nama_siswa',
'tgl_lahir',
'jns_klmin'
];
protected $dates = ['tgl_lahir'];
public function getNamaSiswaAttribute($nama_siswa){
return ucwords($nama_siswa);
}
public function setNamaSiswaAttribute($nama_siswa){
$this->attributes['nama_siswa']=ucwords($nama_siswa);
}
public function telepon(){
return $this->hasOne('App\Telepon', 'id_siswa');
}
}
Telepon.php (model)
class Telepon extends Model
{
protected $table = 'telepon';
protected $primKey = 'id_siswa';
protected $fillable = [
'id_siswa',
'no_telepon',
];
public function siswa(){
return $this->belongsTo('App\Siswa', 'id_siswa');
}
}
Edit and update function controller shown as follows :
public function edit($id){
$siswa = Siswa::findOrFail($id);
$siswa->no_telepon = $siswa->telepon->no_telepon;
return view('siswa.edit', compact('siswa'));
}
public function update(Request $request, $id){
$siswa = Siswa::findOrFail($id);
$input = $request->all();
$validator = Validator::make($input, [
'nisn'=>'required|string|size:4|unique:siswa,nisn,'.$request->input('id'),
'nama_siswa'=>'required|string|max:30',
'tgl_lahir'=>'required|date',
'jns_klmin'=>'required|in:L,P',
'no_telepon'=>'sometimes|numeric|digits_between:10,15|unique:telepon,no_telepon,'.$request->input('id').',id_siswa',
]);
if ($validator->fails()) {
return redirect('siswa/'.$id.'/edit')->withInput()->withErrors($validator);
}
$siswa->update($request->all());
$telepon = $siswa->telepon;
$telepon->no_telepon = $request->input('no_telepon');
$siswa->telepon()->save($telepon);
return redirect('siswa');
}
I got Trying to get property of non-object error in edit function, line "$siswa->no_telepon = $siswa->telepon->no_telepon;".
When we call edit view inside edit controller, it will give a form which inside of it has previous saved data. no_telepon itself is a column from Telepon table, not Siswa, so how to show telephone saved data for editing purposes is the problem. FYI, create works just fine, and no_telepon data saved in Telepon table. So, how about this one? Any help appreciated.
It's probably because you don't have any 'App\Telepon' in the database with 'id_siswa' pointing to the id of the record from table siswa.
You can ommit this error in this way:
public function edit($id){
$siswa = Siswa::findOrFail($id);
$siswa->no_telepon = $siswa->telepon ? $siswa->telepon->no_telepon : '';
return view('siswa.edit', compact('siswa'));
}

Resources