I'm using eloquent to build a query but i'm stuck in the final phase.
$city = City::where('name', $event)->first()->event;
This is working and returns all 3 events for this city, as shown in the screenshot
I want to perform another where for the events, so i can select only 1 based on criteria but it's not working.
I have tried the following
$city = City::where('name', $event)->first()->event->where('id', 1);
and it's giving me the following error
Call to undefined method Illuminate\Database\Eloquent\Collection::where()
Your very example makes no sense, since all you need is:
$eventId = 1;
Event::find($eventId);
In case you wanted to check if that even is related to the city:
Event::where('city_id', $cityId)->find($eventId); // Event model or null
or a bit complicated in this case, but generic solution for any relation type:
Event::whereHas('city', function ($q) use ($cityId) {
$q->where('id', $cityId);
})->find($eventId); // model or null
And finally, if you used find instead of where:
City::where('name', $event)->first()->event->find(1);
City::where('name', $event)->first()->event()->find(1);
It would return the same Model.
This is because find it does basically the same in the context of a query builder:
City::where('name', $event)->first()->event()->where('id', 1)->first();
// equals to:
City::where('name', $event)->first()->event()->find(1);
but it is also a method of the collection:
$someCollection->find($someId); // returns single Model
If you already have the id (1), you can do something like:
$city = City::where('name', $event)->where('id', 1)->first();
But I think you'd rather want the city_id:
$city = City::where('name', $event)->where('city_id', 3)->first();
Solution
The solution is to use event()-> instead of event->
This query is returning the 1st record of the relationship, Which is what i needed.
Thanks everyone!
$city = City::where('name', $event)->first()->event()->where('id', 1)->get();
Related
I'm making a query using the following line:
$items = $this->model->with('subCategory')->get();
But I want to put a query inside the with() method, because I just want to get the items from with() where the status is equal to 0.
How can I achieve this?
There is an "eager loading" in L5 documentation. Here
$items = $this->model->with(['subCategory' => function ($query) {
$query->where('status', 0); }])->get();
These are called eagarload constraints, you can achieve your result using a closure
For example
$items = $this->model->with(['subCategory'=>function($q){
$q->whereId('5');
//or any other valid query builder method.
}])->get();
Let me know how you get on.
I’m new to Laravel. I’m using Laravel 5.2 and I’ve faced a problem in inserting data in to pivot table which I used to handle a many to many relationship. For passing data into the sever I’m using a jquery ajax post request. It’s code is as follows.
$("#btnSave").click(function(){
var path = JSON.stringify(route);
var token = $('input[name="_token"]').val();
$.post("/tour",
{
tourname: $("#name").val(),
startpoint: $("#select_startpoint").val(),
endpoint : $("#select_endpoint").val(),
waypoints : path,
'_token': token
},function(){
alert("Path has been saved");
window.location.href = "/tour";
}); });
Here route is a JavaScript array with set of strings and I’m using Json to pass the values in server. Here I’m using an RESTful resource controller to handle the request and its store method is as follows.
public function store(Request $request){
$user = Auth::user();
$tour = new Tour;
$tour->name = $request->tourname;
$tour->user_id = $user->id;
$tour->startpoint = $request->startpoint;
$tour->endpoint = $request->endpoint;
$tour->save();
$json = $request->waypoints;
$waypoints = json_decode($json);
foreach($waypoints as $waypoint){
$city = City::where('name', '=', $waypoint)->firstOrFail();
$tour->cities()->attach($city->id);
} }
Here in inserting data into pivot table I want obtain the city_id of a particular city from the database first, as I only have it’s name in the array.
As I execute the code the tour table get updated correctly but the pivot table (city_tour) does’nt. When I was further debugging I noticed when a integer value is custom assigned (As example: $tour->cities()->attach(2); ) the code works fine. It seems there is a problem in assigning the value to the $waypoint variable inside the query. But I can’t figure it out, help is much appreciated.
You could try where('name', 'LIKE', "%$waypoint%" )..... "=" usually doesn't play well with strings unless its an exact match.
LIKE in SQL gets closest match.
Use of % with LIKE:
searching for the City 'Algiers'.
this would find the city
$city = 'Algiers';
City::where('name', 'LIKE', "$city" )->firstOrFail();
if you have a white space then you might get nothing
$city = ' Algiers';
City::where('name', 'LIKE', "$city" )->firstOrFail();
if you use % then the space or character is ignored.
$city = ' Algiers'; //extra space on the end
City::where('name', 'LIKE', "%$city" )->firstOrFail();
or if you want to ignore any deviations from the end of the word:
$city = 'Algier'; //with 's' missing
City::where('name', 'LIKE', "$city%" )->firstOrFail();
or you dont have to use LIKE but you make sure the $city is in the column.
Hope that helps
I have tried various methods to resolve this issue, but none worked for me.
1st method:
$title = Character::find($selected_char->id)->title()->where('title', '=', 'Castle');
$title = $title->where('title', '=', 'City');
$title = $title->get();
2nd method:
$title = Character::find($selected_char->id)->title()->where('title', '=', 'Castle')->where('title', '=', 'City')->get();
3rd method:
$title = DB::select(DB::raw("select * from titles where titles.char_id = 5 and title = 'Castle' and title = 'City'"));
None of the above methods work. If I take only one where clause it works perfectly. Example:
$title = Character::find($selected_char->id)->title()->where('title', '=', 'City')->get();
$title = Character::find($selected_char->id)->title()->where('title', '=', 'Castle')->get();
I even tried to take another column than title, but it doesn't work with a second where function. I want to retreive the rows from titles table where the title is City AND Castle I have used multiple where clauses before in a single select statement and it worked. Not now. Any suggestions? Thanks in advance.
You said:
I want to retreive the rows from titles table where the title is City AND Castle
You may try this:
$rowCOllection = DB::table('titles')
->whereIn('title', array('City', 'Castle'))->get();
Using multiple where:
$rowCOllection = DB::table('titles')
->where('title', 'City')
->where('title', 'Castle')->get();
If you want to add another where clause for titles.char_id then you may use it like:
$rowCOllection = DB::table('titles')
->where('title', 'City')
->where('title', 'Castle')
->where('char_id', 5)->get();
You may chain as much where as you need before you call get() method. You can add the where('char_id', 5) after the whereIn like whereIn(...)->where('char_id', 5) and then call get().
If you have a Title model then you may do the same thing using:
Title::where(...)->where(...)->get();
Same as using DB, only replace the DB::table('titles') with Title, for example:
$rowCOllection = Title::where('title', 'City')
->where('title', 'Castle')
->where('char_id', 5)->get();
What about Character here ?
I don't really know how work your double ->where( in php, but in sql here is the mistake :
When you say where title = 'a' and title = 'b', it's like you say : ok give me something where 0=1 it returns nothing.
You can do :
select * from titles where titles.char_id = 5 and (title = 'Castle' or title = 'City')
Retrieve all data where title equals castle or city
Or
select * from titles where titles.char_id = 5 and title IN ('Castle','City')
Retrieve all data where title equals castle or city using IN
I'm pretty sure you will find a way to do that in PHP too.
Assuming you are using Laravel 4
And Character is your model extended from Eloquent
don't mix FIND and WHERE.
Find is for single usage find AND sorting afterward (so order by, and etc)
So if you want to chain up your query
Character::where()->where()->where()-get() (don't forget the get or else you wont get a result)
this way you respect eloquent's features.
Note your first method with ->title() is flawed because your calling a function that you custom created inside your model - thats why it wouldn't have worked.
Note: WereWolf Alpha's method will also work IF you don't want to use Eloquent because the code that he presented will work but thats Fluent notation...so take your pick.
How to merge this two queries ?
$data = DB::table('category_to_news')
->where('category_to_news.name', ucwords($category))
->remember(1440)
->count();
and
$data = DB::table('category_to_news')
->where('category_to_news.name', ucwords($category))
->remember(1440)
->get();
So, as far as I understand from your comment, you simply want to get all records from the table category_to_news and you want to know how many records are in there, right?
MySQL's count is an aggregate functions, which means: It takes a set of values, performs a calculation and returns a single value. If you put it into your names-query, you get the same value in each record. I'm not sure if that has anything to do with 'optimization'.
As already said, you simply run your query as usual:
$data = DB::table('category_to_news')
->where('name', ucwords($category))
->remember(1440)
->get(['title']);
$data is now of type Illuminate\Support\Collection which provides handy functions for collections, and one them is count() (not to be confused with the above mentioned aggregate function - you're back in PHP again, not MySQL).
So $data->count() gives you the number of items in the collection (which pretty much is an array on steroids) without even hitting the database.
Hi DB class dont return collection object it give error "call member function on array" but eloquent return collection object. for above code we can use collect helper function to make it collection instance then use count and other collection methods https://laravel.com/docs/5.1/collections#available-methods .
$data = DB::table('category_to_news')
->where('name', ucwords($category))
->remember(1440)
->get();
$data = collect($data);
$data->count();
You my get it using:
$data = DB::table('category_to_news')
->where('name', ucwords($category))
->remember(1440)
->get();
To get the count, try this:
$data->count();
Why you are using DB::table(...), instead you may use Eloquent model like this, create the model in your models directory:
class CategoryToNews extends Eloquent {
protected $table = 'category_to_news';
protected $primaryKey = 'id'; // if different than id then change it here
}
Now, you may easily use:
$data = CategoryToNews::whereName(ucwords($category))->get();
To get the count, use:
$data->count();
I am currently building an API, I want to be able to search the API via the query string. So for example http://api.dev/?q=12
I can get the value entered but how do I then use this to search the database?
if ($q = Input::get('q'))
{
return( ModelName::where('id', '=', $q));
}
This doesn't seem to change the search and the same data is just returned.
ID's are unique so it doesn't surprise me you're getting the same result.
For Laravel I find the query builder to be better at handling search queries instead of Eloquent.
E.g.
$users = DB::table('users')
->where('votes', '>', 100)
->orWhere('name', 'John')
->get();
Hope this helps.
To search from the db with Eloquent you can use both this ways:
ModelName::where('id', '=', $q)->get();
or
ModelName::find($q);
In the second example Laravel assumes that your Primary Key is id, so in case you have another field as your primary you have to overwrite it, by setting the property in the model.
class ModelName
{
...your props
private $primaryKey = 'yourPrimaryKey'
...
}