I have some table with the same two fields:
value, default_value
How to return result with replacing value on default_value when value is null?
I dont use iteration with result collection. I try to make universal solution.
I tried to use local scopes, but seems it is bad decision.
If you use Eloquent, you can create accessor like this:
public function getRealValueAttribute()
{
return $this->value ? $this->value : $this->default_value;
}
and assuming you get results like this:
$items = Model::all();
you can display this field for models like this:
foreach ($items as $item) {
echo $item->real_value;
}
Related
I have this code where I want to select certain values from the table. Counter is my Model.
$today = '2022-03-16';
$tanggal = Counter::select('tanggal')->where('api', 'Agenda')->where('tanggal', $today)->get();
But if i dd($tanggal->tanggal), it returns with an error Property [tanggal] does not exist on this collection instance.
How to get a value from 'tanggal' attribute?
You are using get() method. it will return collection. You can not access any field directly from collection.
You have to need use freach loop to access single property.
$today = '2022-03-16';
$tanggals = Counter::select('tanggal')
->where('api', 'Agenda')->where('tanggal', $today)->get();
forech( $tanggals as $tanggal)
{
dump($tanggal->tanggal);
}
You are trying to access a model property from a Collection, this can be fixed like so:
$tanggal = Counter::where(['api' => 'Agenda', 'tanggal' => $today])->first(['tanggal']);
get() returns a Collection, first() returns a Model.
You can use the collection but then use its .each() method and give it a lambda instead to process each value.
$collection = Counter::select('tanggal')->where('api', 'Agenda')->where('tanggal', $today)->get();
$collection->each(function ($item, $key) {
//write now your code here can do $item->tanggal
});
I have two objects of the same record which I am getting from the database. One is before the update, and the other is after the update. I want to know the column values which are changed during this update query.
$before_update = DeliveryRun::find($id);
$before_update->name = $request->input('name');
$before_update->save();
$after_update = DeliveryRun::find($id);
compare($before_update, $after_update)
I would define a method on your DeliveryRun model which can be used to compare objects of the same type.
Lets say we want to be able to do something like $deliveryRun->compareTo($otherDeliveryRun). That seems like a nice fluid syntax and reads well in my opinion.
What we want to do is get the attributes and their values for the DeliveryRun we're calling compareTo on and then compare them against the attributes and values for the DeliveryRun we provide as an arguement to the compareTo method.
class DeliveryRun extends Model
{
public function compareTo(DeliveryRun $other)
{
$attributes = collect($this->getAttributes())
->map(function ($attribute, $key) use ($other) {
if ($attribute != $other->$key) {
return $key = $attribute;
}
})->reject(function ($attribute, $key) {
return !$attribute || in_array($key, ['id', 'created_at', 'updated_at']);
});
return $attributes;
}
}
The above gets the attributes for the current ($this) DeliveryRun, converts the array returned from getAttributes() to a collection so we can use the map() function and then loops over each attribute on the DeliveryRun model comparing the key and value of each against the $other DeliveryRun model provided.
The reject() call is used to remove attributes which are the same and some attribute keys which you might not be interested in leaving you just the attributes that have changed.
Update
I am saving object in other variable before update $before_update = $delivery_run; but after update $before_update variable I also gets updated
If I am understanding you correctly, you're still comparing the same object to itself. Try something like the following.
$before = clone $delivery_run; // use clone to force a copy
$delivery_run->name = 'something';
$delivery_run->save();
$difference = $before->compareTo($delivery_run);
I would consider using getChanges() as suggested by #Clément Baconnier if all you're doing is looking to get the changes of an object straight after the object has been saved/updated.
Im trying to find the users that has commented the product this way:
public function getUserToRate(Product $product)
{
$userIds = DB::table('product_ratings')->where('product_id', $product->id)->pluck('user_id');
return $userIds;
}
But the thing is that $product->id is null. This is what comes out if I do:
DB::table('product_ratings')->where('product_id', $product->id)->toSql():
select * from `product_ratings` where `product_id` = ?
Why is my $product->id null? I have checked and the model exists, but I cant seem to use it inside the query builder.
Can anyone lend me a hand? Thanks
I don't think you need a product model. So ignore Route Model binding like Product $product. Instead you can use your $oroductId. And query the UserIds like this:
public function getUserToRate( $productId)
{
$userIds = ProductRating::where('product_id', $productId)->pluck('user_id');
return $userIds;
}
Is it possible to return an value for an hasOne relation directly with an Model?
For example:
$List = Element::orderBy('title')->get();
The Element has a "hasOne" Relation to an column:
public function type()
{
return $this->hasOne('App\Type', 'id', 'type_id');
}
How can i now return automatically the "type" for the Model?
At the Moment i am looping through all Elements, and build my own "Array" of Objects, including the Key of "type" in this example. But ill prefer to do this only in my Model.
Ill know how to add a "normal" property, but can it be someone from an relation?
public function getTypeAttribute($value)
{
return // how ?
}
protected $appends = array('type');
Is this possible?
Edit:
A workaround could be to use DB:: to return the correct value - but ill dont thing thats a good workaround: like:
public function getTypeAttribute($value)
{
// make a query with $this->type_id and return the value of the type_name
}
protected $appends = array('type');
you need to eager load your relations when getting the Element:
$list = Element::with('type')->orderBy('title')->get();
then access the type using
foreach ($list as $item) {
echo $item->type->type_name;
}
where type_name would be the name of a column in the types table
Make a query scope and in that scope, join your attributes from other tables.
http://laravel.com/docs/5.1/eloquent#query-scopes
http://laravel.com/docs/5.1/queries#joins
simple issue I presume.
My controller is getting the if to display from the url using $this->uri->segment(3). This will always be a single value. I am putting this in an array to pass to the model with:
$customerid = array(
'id' => $this->uri->segment(3)
);
The controller syntax is below:
function confirm_delete_customer()
{
$data['title']="Confirm Customer Deletion";
$customerid=array(
'id'=>$this->uri->segment(3)
);
//query model to get data results for form
$data=array();
if($query=$this->model_master_data->get_customer_records_to_delete()){
$data['records']=$query;
$this->load->view("master_data/view_master_data_header",$data);
$this->load->view("master_data/view_master_data_nav");
$this->load->view("master_data/view_content_master_data_confirm_customer_deletion",$data);
$this->load->view("master_data/view_master_data_footer");
}
I am then trying to access this array value and pass it to my model to process. If I hard code the array into the model it works as per below syntax:
Model - Manual Syntax is:
function get_customer_records_to_delete()
{
$query = $this->db->get_where('customers', array('id'=>43));
return $query->result();
}
if I try replace this with the array from my controller it fails with error:
Undefined variable: customerid
idea of model that I want to get working:
function get_customer_records_to_delete()
{
$query = $this->db->get_where('customers', $customerid);
return $query->result();
}
I have a feeling it is something small. however is this the best way to get a single record from the database in order to output to a view?
Thanks in advance for the assistance.
The best way to do that is:
function confirm_delete_customer()
{
$data=array();
$data['title']="Confirm Customer Deletion";
$customerId = $this->uri->segment(3);
//Prevent SQL injections
if(!is_numeric($customerId) || empty($customerId)) {
show_error("Bad Request");
}
$query = $this->model_master_data->get_customer_records_to_delete($customerId);
if ($query){
$data['records']=$query;
$this->load->view("master_data/view_master_data_header",$data);
$this->load->view("master_data/view_master_data_nav");
$this->load->view("master_data/view_content_master_data_confirm_customer_deletion",$data);
$this->load->view("master_data/view_master_data_footer");
}
}
and then you can simply call:
function get_customer_records_to_delete($customerId)
{
$query = $this->db->get_where('customers', array('id'=>$customerId));
return $query->result();
}
at your model.
You need to pass the value as an argument to the function so it can access it.
Ex:
get_customer_records_to_delete($customerid)
{
// now $customerid is accessible
$query = ....;
return $……;
}
You should heavily rely on function parameters. Grab the customer id from the controller and send it to the model. Moreover, you can use row() to get a single result from the database.
Controller:
function confirm_delete_customer(){
$data['title']="Confirm Customer Deletion";
$customerid=$this->uri->segment(3);
//query model to get data results for form
$data=array();
if($query=$this->model_master_data->get_customer_records_to_delete( $customerid)) //you are sending customer id as a parameter here
$data['records']=$query;
$this->load->view("master_data/view_master_data_header",$data);
$this->load->view("master_data/view_master_data_nav");
$this->load->view("master_data/view_content_master_data_confirm_customer_deletion",$data);
$this->load->view("master_data/view_master_data_footer");
}}
Model
function get_customer_records_to_delete($customerid)
{
$query = $this->db->get_where('customers', array("id"=>$customerid)); //you are using the customer id sent from the controller here
return $query->row(); //this will return a single row
}
Old thread but the answer is to declare the variable as "public" in the controller (i.e. public $customerid;), in which case it'll be available to your model. In some cases it's probably safer to explicitly pass as an argument. However, when you have several variables, it's useful to have the option to declare them instead.