I have a car_properties table,
My table like:
id , name , value
I have a big form to create a car. There are 40 different inputs. Some of them selectboxes, some of them checkboxes.. I am trying to implement Eav model for this.
I want to add this 40 inputs in one method
I have methods like:
public function set_property($key ,$value){
$set = new CarProperties;
$set->name = $key;
$set->value = $value;
$set->save();
}
public function Createcar(Request $request){
set_property('gearbox',$request->get('gearbox'));
set_property('fuel_type',$request->get('fuel_type'));
..
..
}
What is the proper way to do this? Or can use a foreach or..?
Thanks for help.
You can try something like this:
public function CreateCar(Request $request)
{
foreach ($request->all() as $key => $value)
{
CarProperties::create([
'name' => $key,
'value' => $value
]);
}
}
Related
I need to be able to use an array in session please. I want to store diffrents candidate_id to find the candidates later.
CandidateController :
public function search(Request $request)
{
$data=$request->validate([
'keyword' => 'required',
'word' => 'required',]);
$keyword= $data['keyword'];
$key= $data['key'];
$candidate = candidate::where($key, $keyword)->get();
return view('candidate.list', compact('candidate'));
}
what are the changes that I should do to make a session array that contains [candidate's ids]
and then finding those $candidate using these ids, and return view('candidate.list', compact('candidate')) ? is it possible ?
$candidate = candidate::where($key, $keyword)->get();
after this line loop through the $candidate.
$ids = [];
foreach ($candidate as $obj){
$ids = $obj->candidate_id;
}
session()->push('candidate_ids', $ids);
return view('candidate.list', compact('candidate'));
when you need to get this array from the session just
#foreach (Session::get('candidate_ids') as $id)
{{$id}}
#endforeach
I have user input following the rules below;
public function rules()
{
return [
'phone_number' => 'required|array',
'amount' => 'required|string|max:4',
'phone_number_debit' => 'required|string|max:15',
];
}
I would want to save the data in a model Transaction. For the phone_number it is an array that could have one value or multiple. So that leaves for foreach loop.
This is what I want to achieve, save different rows determined by the number of records in the array.
$transaction = new Trasaction();
$transaction->phone_number = $req->phone_number; //Value in the array
$transaction->amount = $req->amount;
$transaction->phone_number_debit = $req->phone_number_debit;
$transaction->save();
Save diffrent records according to the records in the phone_number array.
However I can not think of a way to achieve this.
Anyone?
try this :
$data = request(['amount', 'phone_number', 'phone_number_debit']);
foreach($data['phone_number'] as $phone_number) {
Trasaction::create([
'amount' => $data['amout'],
'phone_number' => $phone_number,
'phone_number_debit' => $data['phone_number_debit']
]);
}
make sure in your Trasaction modal you've set to fillable property like this :
class Trasaction extends Model
{
protected $fillable = ['amount', 'phone_number', 'phone_number_debit'];
}
There are many ways to do this, in a nutshell:
collect(request('phone_number'))->each(function ($phone) use ($req) {
$transaction = new Trasaction();
$transaction->phone_number = $phone; // element of the array
$transaction->amount = $req->amount;
$transaction->phone_number_debit = $req->phone_number_debit;
$transaction->save();
});
TL;DR
One-to-Many Relationship
In order to get a better code, you can create a transaction_phones table, creating a one-to-many relationship.
You'll create a TransactionPhone model and add this:
public function transaction()
{
return $this->belongsTo(Transaction::class);
}
The TransactionPhone migration:
Schema::create('transaction_phones', function (Blueprint $table) {
$table->increments('id');
$table->integer('transaction_id');
$table->string('phone_number');
$table->timestamps();
});
In your Transaction model you'll have the inverse:
public function phones()
{
return $this->hasMany(TransactionPhone::class);
}
public function addPhone($phone)
{
return $this->phones()->create(['phone_number' => $phone]);
}
And in you Controller:
$transaction = Trasaction::create(request()->only('amount', 'phone_number_debit'));
collect(request('phone_number'))->each(function ($phone) use ($transaction) {
$transaction->addPhone($phone);
});
I hope this answer can help you.
I use Maatwebsite/Laravel-Excel package to upload CSV to DB. Before entering data to DB i wanna do some additional checks with the database. Something like Project_id available in the Project table. Where do i write the required checking function. Is it a proper way to write it in the same controller. I have seen some people create folder In app\Example and write function file in it
UPDATE :
please let me know is this a proper way to do
https://www.youtube.com/watch?v=fS8q_sD1sZM
This the sample CSV format
This the controller function
public function uploadDealerCSV()
{
if(Input::hasFile('file')){
$path = Input::file('file')->getRealPath();
$data = Excel::load($path, function ($reader) {
$reader->ignoreEmpty();
})->get();
if(!empty($data) && $data->count()){
foreach ($data as $key => $value) {
$insert[] = [
'project_id' => $value->project_id,
'dealer_bl_code' => $value->bl_code,
'reporgroup' => 104,
'added_by' => 73,
'updated_at' => '2017-08-08 10:34:54',
];
}
if(!empty($insert)){
DB::table('cts_project_list')->insert($insert);
//dd('Insert Record successfully.');
}
}
}
return back();
}
public function testFunction(){
}
I have a master table jobs with multiple location in separate table job_location. Now I am not able to update/delete, if extra rows found from job_location. Now why I am saying DELETE is because sync() did this, but it's related to many-to-many relation. I am new to laravel, just trying to get eloquent approach to achieve this, otherwise deleting all rows and inserting can be done easily OR updating each and delete remaining is also an option but I wonder Laravel has something for this.
In every request I get multiple job locations(with unchanged/changed city,phone_number,address) which is creating trouble.
Some codeshots:
Model: [Job.php]
class Jobs extends Model
{
protected $fillable = [
'job_id_pk', 'job_name','salary'
];
public function joblocation() {
return $this->hasMany('\App\JobLocation', 'job_id_fk', 'job_id_pk');
}
}
Model:[JobLocation.php]
class JobLocation extends Model
{
protected $fillable = [
'jobl_id_pk', 'job_id_fk','city', 'address', 'phone_number'
];
public function job() {
return $this->belongsTo('\App\Jobs', 'job_id_fk', 'job_id_pk');
}
}
Controller:[JobController.php]
function jobDetail() {
if($params['jid']) {
// update
$obj = \App\Jobs::find($params['jid']);
$obj->job_name = $params['name'];
$obj->salary = $params['salary'];
$obj->save();
} else {
// create new
$data = array(
'job_name' => $params['name'],
'salary' => $params['salary'],
);
$obj = \App\Jobs::create($data);
}
// don't bother how this $objDetail has associative array data, it is processed so
foreach ($params['jobLocations'] AS $key => $objDetail) {
$jobLoc = new \App\JobLocation;
$jobLoc->city = $objDetail['city'];
$jobLoc->phone_number = $objDetail['phone_number'];
$jobLoc->address = $objDetail['address'];
$jobLoc->job()->associate($obj);
$obj->jobLoc()->save($jobLoc);
}
}
In this approach I am able to save all job locations, but I am using same function to update also. Please tell how I can update jobLocations if present. I am ok to loose previous entries, but it would be good if previous gets updated and new get entered OR if we have extra entries they get deleted. I know sounds weird but still guide me a way.
Yea, you cannot use the same function, do this
$jobs = \App\Jobs::find($params['jid']);
foreach ($params['jobLocations'] as $key => $objDetail) {
$joblocation = $jobs->joblocation->where('jobl_id_pk', $objDetail['some_id'])->first();
//here update you job location
$joblocation->save();
}
Something like this:
Controller:[JobController]
public function jobDetail() {
if( !empty($params['jid']) ) {
// update
$job = \App\Jobs::find($params['jid']);
$job->job_name = $params['name'];
$job->salary = $params['salary'];
$job->save();
} else {
// create new
$data = array(
'job_name' => $params['name'],
'salary' => $params['salary'],
);
$job = \App\Jobs::create($data);
}
$locationDetails = !empty($params['jobLocations']) ? $params['jobLocations'] : [];
$jobLocations = array_map(function($location) use($job) {
$location = array_merge($location, [ 'job_id_fk' => $job->job_id_pk ]);
return \App\JobLocation::firstOrNew($location);
}, $locationDetails);
$job->jobLocations()->saveMany($jobLocations);
}
Is there a better way of organizing or writing the below controller method in Laravel 5.1?
I want to keep my Controllers short and sweet. I am using a repository setup as i'm building quite a large application and I want to keep everything organised.
Please advise on the best way to organise the below code.
/**
* Show the form for creating a new resource.
*
* #return Response
*/
public function create(CreateTimesheetRequest $request)
{
$data = $request->only('user_id', 'template_id');
$data['submitted_by'] = Auth::user()->id;
$timesheetId = $this->timesheet->createTimesheet($data);
foreach($request->get('row') as $key => $row)
{
foreach($row as $field => $value)
{
$this->timesheet->saveTimesheetRows([
'timesheet_id' => $timesheetId,
'field_id' => $this->timesheetFields->where('name', $field)->first()->id,
'field_name' => $field,
'field_value' => $value,
'field_key' => $key
]);
}
}
return Redirect::back()->withMessage('The timesheet was successfully created.');
}
All I can suggest - move this:
$data = $request->only('user_id', 'template_id');
$data['submitted_by'] = Auth::user()->id;
... into yours request class. For example, into some data() method:
class CreateTimesheetRequest ... {
...
public function data() {
return array_merge(
$this->only('user_id', 'template_id'),
['submitted_by' => Auth::user()->id]
);
}
}
Also, $this->timesheet->saveTimesheetRows(array) looks more like $this->timesheet->saveTimesheetRow(array) for me - name intends to save multiple rows, but you feed that method only with one row per call.
Maybe, you can refactor that method to smth. like this:
function saveTimesheetRows($timesheetId, $key, $rows, $fieldIds) {
foreach($rows as $field => $value) {
$this->saveTimesheetRow([
'timesheet_id' => $timesheetId,
'field_id' => $fieldIds[$field],
'field_name' => $field,
'field_value' => $value,
'field_key' => $key
]);
}
}
function saveTimesheetRow(array $row) {
// old saveTimesheetRows implementation
}
Upd.
And another tip: use Eloquent's keyBy() method like so:
$keyIDs = $this->timesheetFields->whereIn('name', $fields)->get(["name", "id"])->keyBy("name");
So, finally:
public function create(CreateTimesheetRequest $request) {
$data = $request->data();
$timesheetId = $this->timesheet->createTimesheet($data);
foreach($request->get('row') as $key => $row) {
$this->timesheet->saveTimesheetRows(
$timesheetId,
$key,
$row,
$this->timesheetFields
->whereIn('name', array_keys($row))
->get(["name", "id"])
->keyBy("name") // probably, can be moved into $this->timesheetFields implementation
);
}
return Redirect::back()->withMessage('The timesheet was successfully created.');
}