I am trying to replicate table row and its relationship.
but I am getting error message that replicate() does not exist,
I have seen on stackoverflow that many have used replicate() without any issue, but i am getting this error
my controller code
public function copyshowtime($cinema_id,$show_date)
{
$date=new Carbon($show_date);
$current_show_date=$date->format('Y-m-d');
$next_show_date=$date->addDay()->format('Y-m-d');
$movieshowtime=Movies_showtimes::with('showdata')->where([['cinema_id','=',$cinema_id],['show_date','=',$current_show_date]])->get();
$newshowtime=$movieshowtime->replicate();
return $newshowtime;
}
Is there any namespace i have to use for using replicate() , I am unable to get solution from laravel website also.
help is appreciated.
You can use replicate() on a model but not on a collection.
By fetching your records using get() you are returning a collection.
If you are just expecting one record to be returned then replace get() with first() and then replicate() should exist as it will be returning an instance of the model rather than a collection:
public function copyshowtime($cinema_id,$show_date)
{
$date=new Carbon($show_date);
$current_show_date=$date->format('Y-m-d');
$next_show_date=$date->addDay()->format('Y-m-d');
$movieshowtime=Movies_showtimes::with('showdata')->where([['cinema_id','=',$cinema_id],['show_date','=',$current_show_date]])->first();
$newshowtime=$movieshowtime->replicate();
return $newshowtime;
}
You will also need to save() the $newshowtime.
This code worked perfectly for me
public function copyshowtime($cinema_id,$show_date)
{
$date=new Carbon($show_date);
$current_show_date=$date->format('Y-m-d');
$next_show_date=$date->addDay()->format('Y-m-d');
$movieshowtime=Movies_showtimes::with('showdata')->where([['cinema_id','=',$cinema_id],['show_date','=',$current_show_date]])->get();
foreach ($movieshowtime as $item)
{
$item->show_date=$next_show_date;
$item->show_id=NULL;
$newshowtime=$item->replicate();
$newshowtime->push();
foreach ($item->showdata as $sd)
{
$newshowdata = array(
'showdata_id' => NULL,
'show_id'=>$newshowtime->id,
'category_id'=>$sd->category_id,
'showdata_category'=>$sd->showdata_category,
'showdata_rate'=>$sd->showdata_rate
);
// print_r($newshowdata);
Movies_showdata::create($newshowdata);
}
}
return redirect()->back();
}
Any suggestions to improve this code will be appreciated.
This type of function would help to clone multiple records and add those records in the same table. I tried a similar code flow and worked.
/**
* Clone multiple records in same table
*
* #params int $cinemaId
* #params string $showDate
*
* #return bool $status
*
* #access public
*/
public function copyShowTime($cinemaId, $showDate)
{
$date = new Carbon($showDate);
$currentShowDate = $date->format('Y-m-d');
// Cloned & Create new records
$moviesShowTimeCollection = Movies_showtimes::with('showdata')->where([['cinema_id','=',$cinemaId],['show_date','=',$currentShowDate]])->get();
// Please check that Model name should change according to camelCases - Movies_showtimes to MoviesShowtimes
if(!$moviesShowTimeCollection->isEmpty()) {
$moviesShowTimeData = $moviesShowTimeCollection->toArray();
foreach ($moviesShowTimeData as $key => $value) {
$primaryKey = 'show_id'; // Needs to check the table primary key name
$primaryId = $value[$primaryKey];
$moviesShowTimeObj = Movies_showtimes::find($primaryId);
// below code can modify while cloaning
//$clonedMoviesShowTimeObj = $moviesShowTimeObj->replicate()->fill([
// 'column_name' => $updatedValue
//]);
$clonedMoviesShowTimeObj = $moviesShowTimeObj->replicate(); // just to clone a single record
$status = $clonedMoviesShowTimeObj->save();
}
}
}
Cheers!
You can easily replicate rows with new changes in that rows
$apcntReplicate = TrademarkApplicantMap::where('trademark_id', $trdIdForPostAssesment)->get();
foreach($apcntReplicate as $oldapnctdata)
{
$apcntreplicated = $oldapnctdata->replicate() ;
//update row data which will newly created by replicate
$apcntreplicated->row_name = $newrowdata;
//save new replicated row
$apcntreplicated->save();
}
Don't use toArray() then each element in the foreach loop will be an Eloquent object.
Related
i have a problem that when i get data from other api and want if same title wont save to api. Each time getting data from the api is 20 and want to save it to the database without duplicate. Please help me. Thank you very much!!!
public function getTitle($title){
$title = $this->posts->where('title', $title)->get();
return $title;
}
public function getApi(Request $request){
$url = "https://newsapi.org/v2/top-headlines?sources=techcrunch&apiKey=87384f1c2fe94e11a76b2f6ff11b337f";
$data = Http::get($url);
$item = json_decode($data->body());
$i = collect($item->articles);
$limit = $i->take(20); // take limited 5 items
$decode = json_decode($limit);
foreach($decode as $post){
$ite = (array)$post;
$hi = $this->getTitle($ite['title']);
dd($ite['title'], $hi);
if($ite['title']==$hi){
dd('not save');
}
else{
dd('save');
}
//dd($hi, $ite['title']);
// create post
$dataPost = [
'title'=>$ite['title'],
'description'=>$ite['description'],
'content'=>$ite['content'],
'topic_id'=>'1',
'post_type'=>$request->type,
'user_id'=>'1',
'enable'=>'1',
'feature_image_path'=>$ite['urlToImage']
];
//dd($dataPost);
//$this->posts->create($dataPost);
}
return redirect()->route('posts.index');
}
You can use first or create for saving data in database if title name is new. using firstOrNew you dont have to use any other conditions
for example:-
$this->posts->firstOrCreate(
['title' => $ite['title']],
['description'=>$ite['description'],
'content'=>$ite['content'],
'topic_id'=>'1',
'post_type'=>$request->type,
'user_id'=>'1',
'enable'=>'1',
'feature_image_path'=>$ite['urlToImage']]);
firstOrNew:-
It tries to find a model matching the attributes you pass in the first parameter. If a model is not found, it automatically creates and saves a new Model after applying any attributes passed in the second parameter
From docs
If any records exist that match your query's constraints, you may use
the exists and doesntExist methods
if($this->posts->where('title', $title)->doesntExist())
{
// save
} else {
// not save
}
I am using Laravel 6. I am trying to create a validation system with a form to create a meeting.
When a user creates a meeting with participants that are already occupied in another meeting, a message should appear in the view with the name of the participants already occupied.
For some reason the function that should find the name of the participants doesn't work. I pass an id during a foreach loop but when I run the form appears the following message: "Trying to get property 'name' of non-object".
The strange thing is that the id passed to the function are OK, but if I write a number (for example "8") in place of $id in the query appears correctly the name "Chris" in the view.
The format of the column "id_participants" in the table meetings is the following "23;7;6".
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
use DB;
use App\User;
class CheckParticipant implements Rule
{
protected $participants_occupied = array();
/**
* Create a new rule instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
$participants = request('participants');
foreach($participants as $participant) {
$meetings = DB::table('meetings')
->where('is_active', '1')
->where('date', request('date_meeting'))
->where(function ($query) {
$query->where(function($sub_q) {
$sub_q->where('start_hour', '>=', request('start'))
->where('start_hour', '<', request('end'));
})
->orWhere(function($sub_q) {
$sub_q->where('start_hour', '<', request('start'))
->where('end_hour', '>=', request('end'));
})
->orWhere(function($sub_q) {
$sub_q->where('end_hour', '>', request('start'))
->where('end_hour', '<=', request('end'));
});
})
->where(function ($query) use($participant) {
$query->where('id_participants', $participant)
->orWhere('id_participants', 'like', '%;'.$participant)
->orWhere('id_participants', 'like', $participant.';%')
->orWhere('id_participants', 'like', '%;'.$participant.';%');
})
->get();
if(count($meetings) > 0) {
array_push($this->participants_occupied, $participant);
}
}
if(count($this->participants_occupied) > 0) {
return false;
} else {
return true;
}
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
for($i = 0; $i < count($this->participants_occupied); $i++) {
$this->participants_occupied[$i] = $this->getNameSurnameById($this->participants_occupied[$i]);
}
return 'The participants are already occupied at that time: ' . implode(',', $this->participants_occupied);
}
public function getNameSurnameById($id)
{
$users = User::all()->where('id', 18)->first(); //if I write a number in place of $id everything works
return $users->name;
}
}
I would like that this program works dynamically. I suppose there is something wrong in the query with the variable $id. Is someone able to help me?
UPDATE:
I solved the problem modifying the message function as follows:
public function message()
{
$arr_names = array(); //I created this array
for($i = 0; $i < count($this->participants_occupied); $i++) {
array_push($arr_names, $this->getNameSurnameById($this->participants_occupied[$i]));
}
return 'The following participants are already occupied at that time: ' . implode(', ', $arr_names);
}
I suppose that the problem consisted that I gave a string value (the name of the participant) to an array that had integers values (The id of the participant). I solved creating a new empty array and I pushed the names to the new array.
You may find it much easier to grab your ids based on some type of Laravel object, rather than an array. I suspect that the array has an incorrect value (not an id) at the index of $i during the loop at some point. And, as pointed out in the comments by #Cristóbal Ramos Merino, you are setting the variable to a potential string (the user name) at the same time as you are trying to pass the possible id through to the getNameSurnameById() method.
I would grab all of the ids passed from the form, do a DB query on User to see who is already occupied, and then just pull the name from the resulting collection.
Something like:
$allFormUsers = User::whereIn('id', $formIds)->get();
Then loop on this to get the names of those occupied:
$occupiedNames = [];
foreach($AllFormUsers->where('occupied', 1) as $u){
$occupiedNames[] = $u->name;
}
I have no idea how you are tracking the occupied - and so the above code is little more than pseudo code, but hopefully will give you an idea of how to do this without the array / concurrency. This also is a little less work on the Database, since you have one query, instead of looping on individual queries each time. You can even pull all users first so you have them stored, and then do a where('occupied', 1) against the collection if you like, as in the above loop. (Assuming that's how you track occupied)
I am developing a system that uses Maatwebsite to read and write data to the database from an excel sheet, which is working fine. Now before inserting the data, the system checks for the entries in parent table. And if there is any record that matches the record of the sheet, the system inserts foreign key to the child schema and if there's not, the system creates one first and then insert it's id as foreign key.
Here's the import class:
public function collection(Collection $rows){
$sub_chap = SubChapter::where(['chap_id' => $this->chap_id])->get();
$chapter = Chapter::where(['chap_id' => $this->chap_id])->first();
$author = Author::where(['author_status' => 1])->get();
$book = $chapter->book_id;
$author_id = 0;
$sub_chap_id = 0;
/* Working perfectly fine here...
foreach($author as $a){
echo $a->a_name."\r";
}
*/
foreach ($rows as $row){
if($row['quote_english'] != ""){
foreach($sub_chap as $sub){
if(trim($sub->sub_chap_english) == trim($row['sub_chap_english'])){
$sub_chap_id = $sub->sub_chap_id;
break;
} else{
$sub_chap_id = 0;
}
}
if($author->count() > 0){
foreach($author as $athr){
$author_id = (trim($athr->author_name) == trim($row['author_name']))? $athr->author_id : $author_id = 0;
}
}
if($author_id == 0){
$author = Author::create([
'author_name' => $row['author_name'],
...
...
'author_status' => 1,
]);
$author_id = $author->author_id;
}
$quote = Quote::create([
'quote_english' => $row['quote_english'],
'author_id' => $author_id,
'sub_chap_id' => $sub_chap_id,
'chap_id' => $this->chap_id,
'book_id' => $book
]);
}
}
}
It's saying:
Trying to get property 'author_name' of non-object
I know this error comes when you try to access an object's property from a non-object instance. get() is returning the collection object as usual and working fine outside the foreach() loop. what i can't figure out is why it's not working inside the loop. Any help would be appreciated!
I still can't figure out why it's saying that and seems like no else also. So I think it's about time I post the solution I came up with. I found a way around it, So, basically what I did was I stored the whole collection to a global variable and accessed it in the loop.
Here's the code:
/**
* Global variable for raavi's data.
*/
public $author;
/**
* Construction function.
*
* #param int $id
* #param Collection $arr
*/
function __construct($arr) {
$this->author= $arr;
}
/**
* This method is responsible for inserting the excel
* sheet's rows data to the database schema.
*
* #param Collection $rows
*/
public function collection(Collection $rows){
// other code as it is...
foreach($this->author['author'] as $athr){
$author_id = (trim($athr->a_name) == trim($row['author_name']))? $athr->a_id : 0 ;
}
}
and in my importing controller's import method:
$quotes = Excel::import(new QuotesImport(compact('author')));
Working fine till now. If there's some improving or anything that needs to be change, kindly feel free. I would appreciate it.
I'm using $casts to save data in array to database. I have an issue with that.
How can i push data to an existing array in the database?
For example i have already an array of data in my db column like: ["some_data", "another_el"] and so on and in the Controller i want to push in this array in db some other data from input.
$brand = Brand::find($request->input('brand'));
$brand->model = $request->input('model');
$brand->update();
Pushing data like this.
You cannot do this with Eloquent's Mass Assignment functions (update, create, etc). You must pull down your field, change it, then save the model.
$collection = collect($brand->field);
$collection->push($myNewData);
$brand->field = $collection->toJson();
$brand->save();
Way 1
$brand = Brand::find($request->input('brand'));
$brand->model = array_merge($brand->model, [$request->input('model')]);
$brand->update();
Way 2 (my favorite because it encapsulates the logic)
$brand = Brand::find($request->input('brand'));
$brand->addModel($request->input('model'));
$brand->update();
And on Entity:
public function addModel($value)
{
$this->model = array_merge($this->model, [$value]);
}
Optional
And on Entity (instead $casts):
public function setModelAttribute($value)
{
$this->attributes['model'] = json_encode($value);
}
public function getModelAttribute($value)
{
return json_decode($value, true);
}
I have images for articles, and when I am updating article I would like to check if the images are the same, if not I would like to delete them but if it is possible I would like to delete the whole collection without another query, something like what I have in the code below $images->delete();.
This is my function:
$images = Media::where('article_id', $article->id)->get();
foreach($images as $image) {
$article_images[] = $image->original_name;
}
foreach($files as $file) {
$filePathArr = explode('/', $file);
$fileName = array_pop($filePathArr);
$originalFile = explode('-', $fileName);
$originalFileName = array_pop($originalFile);
$newFiles[] = $originalFileName;
}
if ($newFiles != $article_images){
$images->delete();
}
You just can't delete from database without making a query.
You will have to make new request like this:
Media::where('article_id', $article->id)->delete();
It's just one simple query, so there shouldn't be any performance penalty.
If we are talking about collection with 100's of items, you can optimize the query like this:
Media::whereIn('id', $images->pluck('id'))->delete();
If you have your Models linked, you can.
Class Exercise.php:
/**
* Exercise belongs to exactly one lecture
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function lecture()
{
return $this->belongsTo('\App\Lecture');
}
and Class Lecture.php:
/**
* Gets all the exercises asociated to this lecture
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function exercises()
{
return $this->hasMany('\App\Exercise');
}
Then you can in your controller simply do:
public function delete($id, DeleteLectureRequest $request)
{
$lecture = Lecture::findOrFail($id);
$lecture->exercises()->delete(); // easy
}
(Imagine that your Article == my Lecture, and your Media == my Exerises)
Of course, at first you have to set properly foreign keys in your DB and link your Models that way.
I'd delete a whole collection by the doing following after calling Model::get() or Model::all()
$posts = Post::all();
// Logic
// More logic
$posts->map->delete();