I have in my database many ads , I want to select one from theme by name I try but I get a null return
public function index()
{
# code...
// $Ads = ads::all();
// return $this->sendResponse($Ads->toArray(), 'Ads read succesfully');
$column = 'name'; // This is the name of the column you wish to search
$Ads = ads::where($column)->first();
return response()->json(['success'=> true,'ads'=>$Ads, 'message'=> 'Ads read succesfully']);
}
and this what I get in post man:
{
"success": true,
"ads": null,
"message": "Ads read succesfully" }
There are some things to note before you dig in:
You need to have Request variable so that you can fetch the user input or if its static then just provide it static. However, static doesnt make sense so I am providing a code that will take input variable.
You need to compare the value with column name in order to fetch it.
Name of the models should be singular form and start with capital as its same as class name so you should use Ad instead of ads, ads is proper for table name, not for model name.
Considering above notes, here is the code which will work for you:
public function index(\Illuminate\Http\Request $request)
{
# code...
$column = 'name'; // This is the name of the column you wish to search
$columnValue = $request->input('name');// This is the value of the column you wish to search
$Ads = Ad::where($column, $columnValue)->first();
return response()->json(['success'=> true,'ads'=>$Ads, 'message'=> 'Ads read succesfully']);
}
Related
I am trying to make my URL more SEO friendly on my Laravel application by replacing the ID number of a certain object by the name on the URL when going to that specific register show page. Anyone knows how?
This is what I got so far and it displays, as normal, the id as the last parameter of the URL:
web.php
Route::get('/job/show/{id}', ['as'=>'website.job.show','uses'=>'HomeController#show']);
Controller method
public function show($id){
$job = Job::findOrFail($id);
return view('website.job')->with(compact('job'));
}
Blade page where there is the link to that page
{{$job->name}}
You can overwrite the key name of your Job model:
public function getRouteKeyName()
{
return 'name';
}
Then in your route simply use {job}:
Route::get('/job/show/{job}', ...);
And to call your route:
route('website.job.show', $job);
So your a tag would look like this:
{{ $job->name }}
Inside your controller, you can change the method's signature to receive the Job automatically:
public function show(Job $job)
{
return view('website.job')
->with(compact('job'));
}
For more information, look at customizing the key name under implicit binding: https://laravel.com/docs/5.8/routing#implicit-binding
You need simply to replace the id by the name :
Route::get('/job/show/{name}', ['as'=>'website.job.show','uses'=>'HomeController#show']);
In the controller action:
public function show($name){
//Make sure to replace the 'name' string with the column name in your DB
$job = Job::where('name', $name)->first();
return view('website.job')->with(compact('job'));
}
Finally in the blade page :
{{$job->name}}
2 options:
1) one is like #zakaria-acharki wrote in his comment, by the name of the job and search by the name for fetching the data
2) the second is to do it like here in stackoverflow
to build the url with the id/name
in this way you will make sure to fetch and show the relevant job object by the unique ID
the route:
Route::get('/job/show/{id}/{name}', ['as'=>'website.job.show','uses'=>'HomeController#show']);
in the controller, update the check if the name is equal to the job name (in case it was changed) to prevent duplicate pages url's
public function show($id, $name){
$job = Job::findOrFail($id);
// check here if( $job->name != $name ) {
// redirect 301 to url with the new name
// }
return view('website.job')->with(compact('job'));
}
in the blade.php :
{{$job->name}}
I am trying to get Laravel to update a database record, if it's already exists. This is my table:
id | booking_reference | description | date
------------------------------------------------------
PRI KEY | UNIQUE | MEDIUM TEXT | DATE
AUTO INC | |
My model looks like this:
Document.php:
class Document extends Model
{
protected $fillable = [
'booking_reference', 'description', 'date'
];
}
And my controller, looks like this - please note that it's webhook() that's being called.
DocumentController.php:
class DocparserController extends Controller
{
//This is the function to capture the webhook
public function webhook(Request $request)
{
$document = new Document();
$document->fill($request->all());
//Grab the date_formatted field from our request.
$document->date = $request->input('date_formatted');
$document->updateOrCreate(
['booking_reference' => $document->booking_reference],
//How can I do so it updates all fields?
);
return response()->json("OK");
}
}
So my problem is, that I cannot figure out how to update my entire row, where the booking_reference is already present.
I want to update all fields (description, date), without having to enter them all like:
['booking_reference' => $document->booking_reference],
['description' => $document->comments, 'date' => $document->date]
Document::updateOrCreate(
['booking_reference' => $request->input('booking_reference')],
$request->all() + ['date' => $request->input('date_formatted')]
);
If you wanted to adjust the request inputs before calling that you could do that mapping and slim this down.
$request->merge(['date' => $request->input('date_formatted')]);
// now $request->all() has `date`
...updateOrcreate(
[...],
$request->all(),
)
That particular field has to be mapped at some point ... if you really really wanted to you could actually have a middleware do this mapping, which would slim this down to just $request->all() as the second array.
Or even set up a mutator for date_formatted that sets date.
Basically this has to happen somewhere, it just depends where.
You can use any one of the following to check if the records exists and run the update query if the data already exists.
$user = Document::where('booking_reference', '=', $request->booking_reference)->first();
if ($user === null) {
// user doesn't exist
}
OR
if (Document::where('booking_reference', '=', $request->booking_reference)->count() > 0) {
// user found
}
Or even nicer
if (Document::where('booking_reference', '=', $request->booking_reference)->exists()) {
// user found
}
And i do not think you can update an entire row of data at once. You have to point which attribute to update to which one.
I would have a private function to normalize the input data:
private static function transformRequestInput($requestArray)
{
$map = ['date_formatted'=>'date'];
foreach($map as $key=>$newKey){
if(isset($requestArray[$key])) {
$requestArray[$newKey] = $requestArray[$key];
unset($requestArray[$key]);
}
}
return $requestArray;
}
And I would use it like so:
$document->updateOrCreate(
['booking_reference' => $document->booking_reference],
self::transformRequestInput($request->all())
);
If you want a class or object to associative array (properties must be public):
$updateArr = (array) $document;
$document->updateOrCreate($updateArr);
However, you use a protected property ($fillable) so you must:
$document = new Document();
$document->fill($request->all());
//Grab the date_formatted field from our request.
$document->date = $request->input('date_formatted');
$reflection = new ReflectionClass($document);
$property = $reflection->getProperty('fillable');
$property->setAccessible(true);
$updateArr = (array) $property->getValue($document);
$property->setAccessible(false);
$document->updateOrCreate($updateArr);
return response()->json("OK");
I have found this:
Move data from one MySQL table to another
But in Laravel it's a bit different. Like him I want a button which deletes a row in a table like this one:
(Updated picture)
Just to have an example. After he hit the button it should move the shown row into the database just like it is shown here and delete it afterwards. I really don't know how to start something like this in Laravel and I really can't find something related.
Maybe this will make it more clear:
$user_input = $request->userInput
$scores = DB::table('cd')
->join('customers', 'cd.fk_lend_id', '=', 'customer .lend_id')
->select('cd.fk_lend_id','cd.serialnumber','users.name', 'cd.created_at as lend on')
->where('cd.fk_lend_id',$request->$user_input)
->get();
Suppose you have two tables: firsts and seconds
For Laravel you must have two Models for these two tables: First and Second respectively.
Now, in your controller,
//import your models
use App\First;
use App\Second;
//create a function which takes the id of the first table as a parameter
public function test($id)
{
$first = First::where('id', $id)->first(); //this will select the row with the given id
//now save the data in the variables;
$sn = $first->serialnumber;
$cust = $first->customer;
$lendon = $first->lend_on;
$first->delete();
$second = new Second();
$second->serialnumber = $sn;
$second->customer = $cust;
$second->lend_on = $lendon;
$second->save();
//then return to your view or whatever you want to do
return view('someview);
}
Remember the above controller function is called on button clicked and an id must be passed.
The route will be something like this:
Route::get('/{id}', [
'as' => 'test',
'uses' => 'YourController#test',
]);
And, your button link like:
Button
This might be a simpler way to do the Laravel "move record" part of this.
use App\Http\Controllers\Controller;
use App\Models\TableOne;
use App\Models\TableTwo;
use Illuminate\Http\Request;
class MoveOneRecord extends Controller
{
public static function move_one_record(Request $request)
{
// before code
// get id
$id = intval( $request->input('id', 0) );
// grab the first row of data
$row_object = TableOne::where('id', $id))->first();
// check if we have data
if (empty($row_object)) { throw new Exception("No valid row data."); }
// convert to array
$row_array = $row_object->toArray();
// unset the row id (assuming id autoincrements)
unset($row_array['id']);
// insert the row data into the new table (assuming all fields are the same)
TableTwo::insert($row_array);
// after code
}
}
I need a little help and I can’t find an answer. I would like to replicate a row from one data table to another. My code is:
public function getClone($id) {
$item = Post::find($id);
$clone = $item->replicate();
unset($clone['name'],$clone['price']);
$data = json_decode($clone, true);
Order::create($data);
$orders = Order::orderBy('price', 'asc')->paginate(5);
return redirect ('/orders')->with('success', 'Success');
}
and i got an error :
"Missing argument 1 for
App\Http\Controllers\OrdersController::getClone()"
.
I have two models: Post and Order. After trying to walk around and write something like this:
public function getClone(Post $id) {
...
}
I got another error
Method replicate does not exist.
Where‘s my mistake? What wrong have i done? Maybe i should use another function? Do i need any additional file or code snippet used for json_decode ?
First of all, make sure your controller gets the $id parameter - you can read more about how routing works in Laravel here: https://laravel.com/docs/5.4/routing
Route::get('getClone/{id}','YourController#getClone');
Then, call the URL that contains the ID, e.g.:
localhost:8000/getClone/5
If you want to create an Order object based on a Post object, the following code will do the trick:
public function getClone($id) {
// find post with given ID
$post = Post::findOrFail($id);
// get all Post attributes
$data = $post->attributesToArray();
// remove name and price attributes
$data = array_except($data, ['name', 'price']);
// create new Order based on Post's data
$order = Order::create($data);
return redirect ('/orders')->with('success', 'Success');
}
By writing
public function getClone(Post $id)
you are telling the script that this function needs a variable $id from class Post, so you can rewrite this code like this :
public function getClone(){
$id = new Post;
}
However, in your case this does not make any sence, because you need and integer, from which you can find the required model.
To make things correct, you should look at your routes, because the url that executes this function is not correct, for example, if you have defined a route like this :
Route::get('getClone/{id}','YourController#getClone');
then the Url you are looking for is something like this :
localhost:8000/getClone/5
So that "5" is the actual ID of the post, and if its correct, then Post::find($id) will return the post and you will be able to replicate it, if not, it will return null and you will not be able to do so.
$item = Post::find($id);
if(!$item){
abort(404)
}
Using this will make a 404 page not found error, meaning that the ID is incorrect.
I have seen some API have simple query that can be constructed in url. For example, I have products table with Product model.
products table properties:
id
product_name
barcode
category_id
description
price
How can I do query in url as below (fields parameter means to select those specified fields):
http://example.com/product?fields=id,product_name,price,barcode&sortby=price
or maybe like this to get price equalto 10.00:
http://example.com/product?fields=id,product_name,price,barcode&price=10.00
I know in laravel we can check the get parameters using $request->has() and get the value using $request->input('fieldname) to check and retrieve the value one by one
But I think there should be a better way to do that or maybe there is a wrapper function that can be used for all controllers to read the query from url get parameters.
Thanks
Ok, here we go. I'll try to be didactic.
TO DO
Build an API that search and returns products from database based on URL parameters.
Properties
First of all, we set an array with our all valid properties.
$props = [
'id',
'product_name',
'barcode',
'category_id',
'description',
'price'
];
Parameters
Let's store all parameters that comes from URL in a variable:
$parameters = Input::all();
Without parameters
If any parameters was passed, we can select all products with their fields and return the result:
if (empty($parameters)) {
$products = Product::all();
return $products;
}
Organizing things
Let's consider that we have 3 "categories" of parameters:
That determines the fields to be selected (optional).
That determines the result order (optional).
That determines the search clauses (optional).
Identifying the fields
For the first category, we'll use the fields parameter that receives a string separating each field by commas.
$fieldsParam = $parameters['fields']; // Gets fields string.
$fieldsParamSplit = explode(',', $fieldsParam); // Split the fields string into array.
$fields = array_intersect($props, $fieldsParamSplit); // Gets only wanted fields.
The order
For the second category, we'll use the sortby parameter that receives a specific field (property) name.
$orderProp = null;
// Check if parameter "sortby" exists and if it is valid.
if (isset($parameters['sortby']) && in_array($parameters['sortby'], $props)) {
$orderProp = $parameters['sortby'];
}
There's some clause?
For the third category, we'll use all parameters (except those mentioned above) to build the where clauses of search.
$clauses = [];
foreach ($props as $prop) {
// Check if the current property is present in parameters.
if (in_array($prop, array_keys($parameters))) {
// Each item represents a where clause.
$clauses[$prop] = $parameters[$prop];
}
}
Building the collection
Now that all the paremeters are validated, we can build the collection of products and return the result.
if ($orderProp) {
$products = Product::where($clauses)->orderBy($orderProp)->get($fields);
} else {
$products = Product::where($clauses)->get($fields);
}
return $products;