Yii composite key in relatins with custom params - activerecord

I want to use composite key in ActiveRecord.
I got two tables.
Quotes and Comments.
Quotes contains pk - id;
Comments pk is composite - module, section, cid
module - module name, where comments come from.
section - section of this module
cid - identificator, in this situaction this is id of quote.
In comments I defined primary key like so.
public function primaryKey()
{
return array('module', 'section', 'cid');
}
Next one, I want to get those records, what related to quotes.
So, in Quotes I declared relation:
'comments' => array(self::HAS_MANY, 'Comment', 'module, section, cid', 'params' => array(
':ypl0' => '"quotes"',
':ypl1' => '"quote"',
':ypl2' => 'id'
)),
The required result is:
SELECT * FROM quotes q
LEFT JOIN comments c ON (c.cid = q.id AND module = "quotes" AND section = "quote")
WHERE c.id IS NULL
SQL is working, relation - not. What I'm doing wrong?

Try the following untested code
'comments' => array(self::HAS_MANY, 'Comment', 'cid','condition'=>'module=:param1 AND section=:param2','params' => array(':param1' => 'quotes',':param2' => 'quote',)),

Related

how to Run SQL insert Using Multiple Database Connections

this my code
DB::connection('mysql2')->insert('INSERT INTO pm_booking_service (id_booking, title, qty, amount) VALUES ('2','restaurant','1','27')' );
I don't know how to do insert Using Multiple Database Connections
but select is working fine
$bookings = DB::connection('mysql2')->select('select * from pm_booking');
When you have a string that starts with a single quote you need to escape any single quotes it contains otherwise they are interpreted as closing the string.
Use parameters to not need to quote the values manually:
DB::connection('mysql2')
->insert('INSERT INTO pm_booking_service (id_booking, title, qty, amount) VALUES (?,?,?,?)', [2,'restaurant',1,27]);
An example of this can be found in the docs as well
This can be rewritten in the query builder as :
DB::connection('mysql2')->table('pm_booking_service')
->insert([
'id_booking' => 2,
'title' => 'restaurant',
'qty' => 1,
'amount' => 27
]);
Update statements are also written similarly:
DB::update(
'update pm_booking_service set qty = ? where id = ?',
[100, 2]
);
This also can be written in the query builder as:
DB::connection('mysql2')->table('pm_booking_service')
->where('id', 2)
->update([ 'qty' => 100 ]);

Laravel whereHas not filtering as expected

The 2 models involved are JobRequest and StationJob. Really their relationship is oneToMany. I have a relationship set up for this $jobRequest->stationJobs().
Further to this I need a hasOne relationship latestStation, based on the same model. I need this relationship to filter my collection of JobRequests based on whether the JobRequest has a latestStation equal to a specified station.
I am expecting to get an empty list of JobRequests because I know the latestStation is equal to id 3 and I am filtering for id 2. Instead I get the jobRequest, with latestStation id 3 even though I am filtering for 2.
Relationship
public function latestStationTest()
{
return $this->hasOne(StationJob::class)->whereNotNull('finished')->latest();
}
Controller
$stationId = $request->station_id;
$jobRequests = JobRequest::with(['latestStationTest'])->whereHas('latestStationTest', function($query) use ($stationId) {
$query->where('station_id', $stationId);
})->get();
Query Result
[2020-10-17 07:39:07] local.INFO: array (
0 =>
array (
'query' => 'select * from `job_requests` where exists (select * from `station_jobs` where `job_requests`.`id` = `station_jobs`.`job_request_id` and `station_id` = ? and `finished` is not null)',
'bindings' =>
array (
0 => 2,
),
'time' => 1.0,
),
1 =>
array (
'query' => 'select * from `station_jobs` where `finished` is not null and `station_jobs`.`job_request_id` in (1) order by `created_at` desc',
'bindings' =>
array (
),
'time' => 0.5,
),
)
I've tried...
Switching with() before or after whereHas makes no difference.
adding ->where() to with() selects the StationJob with the specified id, instead of checking if the latestStation id is equal to the specified id.

Laravel updateOrInsert with 'OR' or 'AND' operator in first arguments?

While it is possible to have multiple arguments for the updateOrInsert in Laravel query builder and what is the operator used by default.
For example in the documentation it is mentioned:
DB::table('users')
->updateOrInsert(
['email' => 'john#example.com', 'name' => 'John'],
['votes' => '2']
);
Does that mean that email && name are checked or does it mean email || name is checked? How can we control it for one or the other if required?
Please forgive me if this is a silly question or if it is not worded as per the correct vocabulary, as I am new to Laravel. I couldn't find this information in the documentation or API.
updateOrInsert() method is used to update an existing record in the database if matching the condition or create if no matching record exists. Its return type is Boolean.
Syntax :
DB::table('blogs')->updateOrInsert(
[Conditions],
[fields with value]
);
In your query :
DB::table('users')->updateOrInsert(
['email' => 'john#example.com', 'name' => 'John'],
['votes' => '2']
);
It will check if email == 'john#example.com' & name == 'john', then it will update votes=2.

Can't add additional where queries in Ardent Model

I'm having a problem using LaravelBook/Ardent. My logic is exclude the soft deleted rows in unique validation using the code:
public static $rules = array(
'name' => 'required|unique:paper_colors,name,deleted_at,NULL',
'description' => 'required|between:2,255',
'code' => 'required'
);
But when I run the updateUniques I'm still getting The name has already been taken. and this sql:
select count(*) as aggregate from `paper_colors` where `name` = '4/0' and `id` <> '2'
I'm expecting the sql will be:
select count(*) as aggregate from `paper_colors` where `name` = '4/0' and `id` <> '2' and `deleted_at` is null
Can someone help me to solve this. I'm stuck almost last night on this. Still can't figure it out how to deal with this.
I found out that Ardent is dropping the Laravel Validation feature: Adding Additional Where Clauses
So my solution to overcome this bug is to add additional code under LaravelBook\Ardent\Ardent#buildUniqueExclusionRules at line: 799, but I didn't do that since I'm depending for their any updates in the future. So I just create a class that extend LaravelBook\Ardent\Ardent and copy buildUniqueExclusionRules and modify it.
if (count($params)>2)
{
$c = count($uniqueRules);
for ($i=1; $i < count($params); $i++, $c++) {
$uniqueRules = array_add($uniqueRules, $c, $params[$i]);
}
}

Selecting on a many table using Linq

I have a recipe table that has a related ingredients table
on one to many basis.
How do I select using Linq ingredients
that have a ingredientName column and it should contain
a specified word.
This is what I tried.
IQueryable<OurRecipes.Domain.Linq2Sql.Recipe> recipes = _dbctx.Recipes.AsQueryable();
foreach (string word in searchdata.Keywords)
{
recipes = recipes.Where(r => r.RecipeTitle.Contains(word));
recipes = recipes.Where(r => r.Ingredients.Where(i => i.IngredientName.Contains(word)));
}
I get cannot convert type 'etc' to bool error.
Any ideas
Malcolm
The error lies here:
recipes = recipes.Where(r => r.Ingredients.Where(i => i.IngredientName.Contains(word)));
The condition inside Where must return a boolean, in this case, the r.Ingredients.Where(i => i.IngredientName.Contains(word)) will not return a boolean, and hence the error.
This is how you can fix the problem:
recipes = recipes.Where(i => i.Ingredients.Any(row=>row.IngredientName.Contains(word)));
r.Ingredients.Where(i => i.IngredientName.Contains(word)));
replace with
r.Ingredients.Any(i => i.IngredientName.Contains(word)));
Btw, I like SQL like syntax more as it more netural. The same:
from r in _dbctx.Recipes
where r.Ingredients.Any(i => i.IngredientName.Contains(word)));
select r;
This will select all recipies that has ingredients with name contains word.

Resources