SELECT text
FROM localization
LEFT JOIN countries
ON countries.country_name_key = localization.key
WHERE countries.country_name_key = localization.key
AND localization.lang = 'ar';
I need to write this query in laravel with eloquent model without relations between the model .
I aggree with MrMarlow. Without Eloquent, you have to use Query Builder. But I think, i have different query:
$results = DB::table('localization')
->leftJoin('countries','countries.country_name_key','localization.key')
->where('countries.country_name_key','localization.key')
->where('localization.lang', 'ar')
->select('localization.text')
->get();
With leftJoin in the query will show all text in localization table altough no relation in countries. So, i think it no need leftJoin to show localization.text field because you just want to show the localization.text field in localization table only.
It works in laravel 5.6.
Hope this helps.
It is my understanding that Eloquent has to use models with relationships to be able to query effectively, so to the best of my (limited) knowledge, I do not believe it's possible.
However, Laravel does ship with Query Builder which will handle this just fine.
Query Builder
By using the DB facade (Illuminate\Support\Facades\DB) you can create the query like so;
$results = DB::table('localization')
->join('countries', 'localization.key', '=', 'countries.country_name_key')
->where('countries.country_name_key', '=', 'localization.key')
->where('localization.lang', '=', 'ar')
->pluck('text');
Documentation for explanation/further research, can be found within the Laravel 5.6 Query Builder Documentation
Edit
If you do decide you must use eloquent, you can create models for existing database tables using something like reliese/laravel, but you would then need to create relationship mapping etc.
Related
Hello I have a problem when I try to make a query to another database.
I have 3 tables: "MarketAgreement" and "MarketTransaction" in the koop_app (mysql) database and the "AgreementEnergia" table in the koop_app_energia database
My Models:
With the "MarketAgreement" model, WhereHas works perfectly for me, but with "AgreementEnergia" I get this error:
I have declared which database each table belongs to but still when I try to do the whereHas crossed between "AgreementEnergia" (found in the koo_app_energia database) and "MarketTransaction" (found in the koop_app database) Laravel tries to find the table in the wrong database.
How can I solve that? Thanks a lot.
I have solved it by simply changing protected $table = 'market_transactions'; for protected $table = 'koop_app.market_transactions';
For a "belongsToMany" relationship, You can do something like that:
public function your_method()
{
$database = $this->getConnection()->getDatabaseName();
return $this->belongsToMany('B', "$database.a_bs", 'a_id', 'b_id');
}
BUT: when you are modelling relationships between data, it implicitly within the same database. It is not expected to do this in two different databases
For a "Has" relationship, Eloquent does not currently support querying for relationship existence across databases. The relationships must exist within the same database (https://laravel.com/docs/8.x/eloquent-relationships#querying-relationship-existence)
PS: please do not put screenshots, but code snippets
I need to use DB::select() statement for a complex query I´m working on that is not returning any results. After some diggin I found out the reason was that the model_type field comparison was not working regardless wheather I use this sintaxis:
select *
from questions
where model_type = "App\Models\Product"
Or this sintaxis:
select *
from questions
where model_type = "App\\Models\\Product"
Even though the second sentence works perfectly on MySQL Workbench, it returns no results in Laravel.
The MySQL table field name is of course model_type and the values are hold as: App\Models\Product and all relationships work perfectly. It seems that there should be a way to specify to Laravel how to compare the values, but I haven´t found it.
Please note that I have to use DB::select() as oposed to Eloquent, since my actual query deals with MySQL MATCH() AGAINST() and some other complexities.
Any help would be welcome. Txs!
Just in case someone else runs into this predicament, I still don´t know why Eloquent is not able to resolve it´s model, but I did find this great article which solves this and other potential situations as well, by decoupling Laravel logic from the information stored in the database. https://josephsilber.com/posts/2018/07/02/eloquent-polymorphic-relations-morph-map#the-default-morph-type
Till today I was relying on Laravel relationships, but since I opened mysql logs I was very disappointed.
When I execute code
Company::with(['users', 'machines'])->get()
mysql.log looks this way
select * from `company` where `company`.`id` = '48' limit 1
select * from `user` where `user`.`company_id` in ('48')
select * from `machine` where `machine`.`company_id` in ('48')
Why Laravel does not use joins for eager fetching? Also, are there any ways of improving perfomance and still using Laravel Models?
I know that Doctrine ORM eager loading works pretty nice by using joins.
Thank you for your help.
If you really want to use joins instead of the Eloquent computed queries, I suppose you could just use the fluent query builder (that comes shipped with Laravel through the DB facade) and stick that code into a method of your model to keep everything nice and SRP.
For instance:
class Company extends Model {
public function sqlWithJoin() {
$users = DB::table('company')
->leftJoin('user', 'company.id', '=', 'user.company_id')
->get();
return $users;
}
}
This would generate a proper join query for you.
As for why you would want to do this, you would have to benchmark both options to see which one gives you the best performance for your specific data. I wouldn't generalize that one option always has better/worse performance than the other.
As stated in the comments, I'm not sure performance-wise why this is the preferred method, but from usability, being able to access a model's relationships as it's own separate property is much easier than working with a join, especially in the event of a many-to-one relationship.
Let's compare the above example using both ->with() and ->leftJoin() methods.
When using ->with() every relationship is defined as a property of Company, accessed via $company->users. It's easy to run a foreach() loop over this property foreach($company->users AS $user) and output information, such as username, email, etc. Also, if the Company has no users, you don't have to worry about displaying empty values (especially important on chaining models using . notation, such as users.user_details).
Now, looking at leftJoin(). If you try to chain multiple leftJoins() on each model and their sub-models, there's a chance you won't get the results you're expecting. Essentially, leftJoin() doesn't handle NULL records as well as individual queries can.
Next, to output a list of a company's users, you would have to run a loop such as:
foreach($company AS $row){
echo $row->username;
echo $row->email;
// etc etc
}
This becomes problematic as Eloquent doesn't handle duplicate properties well at all. For example, if the company has an email field as well as the user, it's anyone's guess which is actually displayed. Unless you do a selectRaw("companies.email AS email, users.email AS user_email)", only one email property is going to be returned. This also applies to columns like id, where multiple are going to be fetched by using leftJoin(), but only one will actually be accessible.
Long story short, leftJoin() comes with the potential for a lot of issues when trying to join multiple tables with the possibility of duplicate information, null information, etc. While the performance of running multiple queries using the ->with() method may not be the best, it allows for easier use in retrieving and displaying information.
We all know that using the Eloquent with('relation') function is not doing a JOIN , but it's making another query to get the relationship.
Is there a way to make a single query using JOIN so we can reduce our MySQL queries ?
As far as I know it's not possible to use JOIN when using Eloquent objects. This is how Eloquent work - it doesn't use joins, it uses separate queries to get related data. So if you want to use joins, you won't be able to use Eloquent objects.
You could create a VIEW in database, and then, create a model in your app. Updated data in VIEW is automatically updated in the related tables. Could be a workaround.
Yeah something like this if you want to do a left join ( use ->join() for a simple inner join)
$query = DB::table('product');
$query->leftJoin('user', 'product.seller_id', '=','user.user_id');
return $query->get();
See the query builder docs for further details: http://laravel.com/docs/4.2/queries#joins
I am creating a backend interface for a site made in Joomla. I am using Laravel to create the backend. Joomla has table prefixes and tend to have long table names there are some of which around 25 characters.
My issue is, I have looked around to see if that you can alias table names (so I don't have to type the table name all the time in the join statement) by I don't seem to be able to find a method for this in the query object.
ModelName::getTable(); // Happens to be a static method.
Any helper much appreciated.
As answered in that StackOverflow question:
How to alias a table in Laravel Eloquent queries (or using Query Builder)?
you can either use aliases while building your query
$users = DB::table('really_long_table_name AS t')
->select('t.id AS uid')
->get();
or define the alias in your Eloquent model
protected $table = 'really_long_table_name AS short_name';