DQL Update with relations - php

Following Models:
class User extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn ( 'iron', 'integer', 4 );
}
public function setUp() {
$this->hasMany ('Field as Fields', array(
'local' => 'id',
'foreign' => 'owner_id'
));
}
}
class Field extends Doctrine_Record {
public function setTableDefinition() {
$this->hasColumn('owner_id','integer',4);
$this->hasColumn('ressource_id','integer',4);
$this->hasColumn('ressource_amount','integer','2');
}
public function setUp() {
$this->hasOne('User as Owner',array(
'local' => 'owner_id',
'foreign' => 'id'
));
}
}
And I try following DQL:
$sqlRessourceUpdate = Doctrine_Query::create()
->update('Field f')
->set('f.Owner.iron','f.Owner.iron + f.ressource_amount')
->where('f.ressource_id = ?',1);
Result:
'Doctrine_Query_Exception' with message 'Unknown component alias f.Owner'
Basicly I just want to update the "iron" attribute from the Field-Owner according to the fields' value

I am guessing you can't reference other tables like that in your query.
This may not be the best way but, here is what I do
$q = Doctrine_Query::create()
->select('*')
->from('Field')
->where('ressource_id = ?',1); //btw resource has one 's'
$field = $q->fetchone();
$field->Owner['Iron'] += $field->ressource_amount;
$field->save();
EDIT:
Actually I don't know if that will work... this is more like what I do
$q = Doctrine_Query::create()
->select('*')
->from('Field')
->where('ressource_id = ?',1); //btw resource has one 's'
$field = $q->fetchone();
$user = $field->Owner;
$user['Iron'] += $field->ressource_amount; // I have never used a += like this, but in theory it will work.
$user->save();

Related

Property [id] does not exist on the Eloquent builder instance in Laravel 8 and Livewire 2.7

My users can create multiple usercar's when selecting from a database of car's. I need to grab the selected car values, but when I dd the values, I get a Property [id] does not exist on the Eloquent builder instance. error. wire:model="car_id" is the select input value used in the code below.
AddUserCar.php
...
class AddUserCar extends Component
{
public $showAnotherModel = false;
// Steps
public $totalSteps = 8;
public $step = 1;
// User
public $super;
public $first_name;
public $last_name;
public $email;
public $status = 1;
public $role = 'Driver';
// Usercar
public $car_id;
public $calc_date;
public $year;
public $model;
// Form Function
public $car_year;
//public $cars;
//public $modelId;
...
public function moveAhead()
{
if($this->step == 1) {
$newCar = Car::where('id', '=', $this->car_id)->get();
dd($newCar->id); // This is where I get error
$this->usercarCreated = Usercar::create([
'year' => $newCar->start_year,
'model' => $newCar->model,
'car_id' => $this->car_id,
'user_id' => Auth::user()->id,
'tenant_id' => Auth::user()->tenant_id,
'calc_date' => now()->format('m-d-Y'),
]);
$this->resetErrorBag();
$this->resetValidation();
}
...
public function render()
{
return view('livewire.add-user-car',
['pageTitle' => 'Add Driver Car']);
}
}
Use ->get() to retrieving all rows from a table :
$cars = Car::where('id', '=', $this->car_id)->get();
foreach($cars as $car){
echo $car->id;
}
// ERROR, because $cars isn't a single row
dd($cars->id);
Use ->first() to retrieving a single row / column from a table.
$car = Car::where('id', '=', $this->car_id)->first();
// or
$car = Car::find($this->car_id);
// WORK
dd($car->id);
$newCar = Car::where('id', '=', $this->car_id)->get();
This statement does not find any data, so $newcar is empty, and an empty object has no ID

Laravel 5.5 - Method paginate not found

I don't know what's wrong, but here's my script at my AppController.
function getData () {
$list_data = MyModel::all()->sortBy('id')->paginate(15);
$count_data = $list_siswa->count();
return view('pages.list', ['list' => $list_data, 'count' => $count_data]);
}
And here's my model
class MyModel extends Model {
protected $table = 'students';
protected $fillable = [
'id',
'name',
'class',
'gender',
'address'
];
}
Any idea? I think the problem is in my controller.
You must paginate a database query not a collection, therefore you must user orderBy instead of combining all with sortBy, I have tested the below code and can confirm it works
function getData () {
$list_data = MyModel::orderBy('id')->paginate(15);
$count_data = $list_data->count();
return view('pages.list', ['list' => $list_data, 'count' => $count_data]);
}

Laravel 5.4: Storing the 'Where' clause in a variable

I want to write a dynamic update query in Laravel which accepts arguments and can be used in whole project.
Following is my Controller function:
public function editquery(Request $request)
{
$city_id = $request->input('city_id');
$city_name = $request->input('city_name');
$tbl = 'city';
$data = ['city_name'=>$city_name];
$wher = ('city_id',1);
General_model::editrecord($data,$wher,$tbl);
return redirect()->action('Admin_controller#cities_page')->with('status','Record Updated Successfully!');;
}
Below is my Model function:
public static function editrecord($data,$wher,$tbl)
{
return DB::table($tbl)->where($wher)->update($data);
}
The only problem here is that I cannot store the value ('city_id',1) in the $wher variable. This is the screenshot of the error:
link to the image file
Is there any other way to do this. Please Help.
The where method accepts an array of conditions.
$table = 'city';
$conditions = [
['city_id', '=', '1']
];
$data = ['city_name' => $city_name];
General_model::editRecord($table, $conditions, $data);
// In your model
public static function editRecord($table, $conditions, $data)
{
return DB::table($table)->where($conditions)->update($data);
}
You can also set multiple conditions.
$conditions = [
['city_id', '=', '1'],
['test', '=', 'test'],
];
Edit
This is the default where method
where($column, $operator = null, $value = null, $boolean = 'and')
Setting the fourth parameter to or will make the condition orWhere.
Example
$conditions = [
['city_id', '=', '1'],
['test', '=', 'test', 'or'],
];
You can't do this
public static function editrecord($data,$wher,$tbl)
{
return DB::table($tbl)->where($wher)->update($data);
}
Since, where is a function; it expects 2 or 3 arguments and not just 1 argument.
You will have to pass both the arguments like so
public static function editrecord($data, $where_column, $where_val, $tbl)
{
return DB::table($tbl)->where($where_column, $where_val)
->update($data);
}
Then, in your controller function
$where_column = 'city_id';
$where_val = 1;
General_model::editrecord($data,$where_column,$where_val,$tbl);
Your code is not exactly in the style of Laravel, why would you want to create a separate static function, if such tasks are easily solved by the standard features of Eloquent / Query Builder?
Eloquent example:
app/City.php
<?php
class City extends Model {
protected $table = 'city';
protected $primaryKey = 'city_id';
protected $fillable = ['city_name'];
}
In your controller:
City::findOrFail($city_id)->update([
'city_name' => $city_name
]);
Query Builder example:
DB::table('city')->where(['city_id' => $city_id])->update([
'city_name' => $city_name
]);
This is much easier to read, understand and support than functions that do similar things in an incomprehensible way.

How to get flexibility in laravel sql query

I want to add a sql filter where('comment_id', '=', 1) to php code
$datas = $this->model->ADD HERE->orderBy('created_at', 'DESC')->paginate(15);
Trying to add the string to code take me hours. How to make it?
Here is my code:
CommentResource.php passing the sql filter as string parameter.
<?php
class CommentResource extends BaseResource
{
public function index()
{
$filter = "where('comment_id', '=', 1)";
return parent::index_filter($filter);
}
CommentResource.php
<?php
class BaseResource extends Controller
{
protected function index_filter($filter)
{
$datas = $this->model->ADD HERE->orderBy('created_at', 'DESC')->paginate(15);
return view($this->resourceView.'.index')->with('datas', $datas);
}
}
As I understand you want to use different types of where as filters in your queries. That's why you want to make them dynamic. I would suggest the following solution for your task:
<?php
class CommentResource extends BaseResource
{
public function index()
{
$filter = [ 'operator' => 'where', 'args' => ['comment_id', '=', 1]];
return parent::index_filter($filter);
}
<?php
class BaseResource extends Controller
{
protected function index_filter($filter)
{
$where = $filter['operator'];
$args = $filter['args'];
$datas = $this->model->$where(...$args)->orderBy('created_at', 'DESC')->paginate(15);
return view($this->resourceView.'.index')->with('datas', $datas);
}
}
However, it will work starting from Php5.6+ because of oeprator ...
I am not sure if I got your requirements correctly, but if you rewrite index_filter to accept field and value separately, then you may user a regular where() from laravel:
protected function index_filter($field,$value)
{
$datas = $this->model->where($field,$value)->orderBy('created_at', 'DESC')->paginate(15);
return view($this->resourceView.'.index')->with('datas', $datas);
}
You can find the docs here. In case you really need more flexibility:
protected function index_filter($filter)
{
$datas = $this->model->whereRaw($filter)->orderBy('created_at', 'DESC')->paginate(15);
return view($this->resourceView.'.index')->with('datas', $datas);
}
Have in mind though that this is really dangerous, as you expose the possibility to inject malicious code, it should be definitely properly escaped beforehand.
My latest code works right. I'll post here.
<?php
class CommentResource extends BaseResource
{
public function index()
{
$options = [
'filters'=>[
[ 'operator' => 'where',
'args' => [
[ 'article_id', '=', $article_id ],
[ 'comment_id', '=', $comment_id ],
// add filter args...
],
],
// add filter operators here...
],
'sorts' => [
'column' => $sortColumn, // change sort column...
'order' => $sortOrder, // change sort order...
],
];
return parent::index_filter($options);
}
<?php
class BaseResource extends Controller
{
protected function index_filter($options, $number=15)
{
$result = $this->model;
foreach ($options['filters'] as $filter) {
$operator = $filter['operator'];
$args = $filter['args'];
$result = $result->$operator($args);
}
if ( $options['sorts'] != [] ) {
$column = $options['sorts']['column'];
$order = $options['sorts']['order'];
$result = $result->orderBy($column, $order);
}
return $result->paginate($number);
}
}
The reason I change ...$args to $args is, when 'args' has more than on value, for example,
'args' => [
[ 'article_id', '=', $article_id ],
[ 'comment_id', '=', $comment_id ],
// add filter args...
],
...$args will change 'args' to one array, but $args will remain 'args' as nest array, which is the operator 'where' want.

Default scope in Yii 1.1

AR model Player:
public function scopes()
{
return array(
'proleague' => array(
'condition' => 'mode = "proleague"',
),
'main' => array(
'condition' => 'mode = "main"',
),
);
}
Using model Player:
Player::model()->
proleague()->
with('startposition')->
findAllByAttributes(... here some condition ...);
^^^ That's all ok. Scope-condition will be executed. But...
In my project I have many places where any scope for Player model doesn't specified and in this cases I need use this scope-condition as default:
'main' => array(
'condition' => 'mode = "main"',
)
If I add defaultScope() method to Player model like this
public function defaultScope()
{
return array(
'condition' => 'mode = "main"',
);
}
the next code
Player::model()->
proleague()->
with('startposition')->
findAllByAttributes(... here some condition ...);
won't run correct. I won't get mode = "proleague" condition, becouse I'll use defaultScope() with mode = "main".
Any suggestions? How can I resolve the problem?
You should just use the resetScope(true) method. It "removes" the defaultScope filter.
$model = Player::model()->resetScope(true)->proleague();
create a new Class for this.
<?php
## e.g. protected/models/
class MyCoreAR extends CActiveRecord
{
/**
* Switch off the default scope
*/
private $_defaultScopeDisabled = false; // Flag - whether defaultScope is disabled or not
public function setDefaultScopeDisabled($bool)
{
$this->_defaultScopeDisabled = $bool;
}
public function getDefaultScopeDisabled()
{
return $this->_defaultScopeDisabled;
}
public function noScope()
{
$obj = clone $this;
$obj->setDefaultScopeDisabled(true);
return $obj;
}
// see http://www.yiiframework.com/wiki/462/yii-for-beginners-2/#hh16
public function resetScope($bool = true)
{
$this->setDefaultScopeDisabled(true);
return parent::resetScope($bool);
}
public function defaultScope()
{
if(!$this->getDefaultScopeDisabled()) {
return array(
'condition' => 'mode = "main"',
);
} else {
return array();
}
}
}
In your code:
// no default scope
$model = Player::model()->noScope()->proleague();
// with default scope
$model = Player::model()->proleague();

Categories