Variable inside laravel query builder is always null - laravel

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;
}

Related

Laravel eloquent order by custom attribute

I have a total_views attribute added to my Product model like this
public function getTotalViewsAttribute(){
return (int)$this->views()->sum('count');
}
views() is a relationship on Product like this
public function views()
{
return $this->morphMany(View::class, 'viewable');
}
What I would like to do is order my Product by the total_views. Or in other words to order by the sum of the views() relationship.
I have tries to ->orderBy('total_views') on the query but it doesn't seem to work as expected.
Any help will be highly appreciated.
Eloquent getter can only work, when the query has been executed, therefor your current code is not working. I would always use withCount(), on the query;
$products = Product ::withCount(['views'])->get();
The count would be on a property named views_count;.
foreach ($products as $product) {
$product->views_count; // get view count
}
And also possible to order by the column, as it will be present in the SQL returned by the query.
Product ::withCount(['views'])->orderBy('views_count', 'desc')->get();

How to use orderBy() with model's method in Laravel

How can I use orderBy to order by a model's method?
Consider the model User and the method
public function fullName() {
return $this->firstName . $this->lastName;
}
I want to do something like orderBy('fullName'). Is this possible? I know I can make equivalent code using Query Builder, but I want to keep my Model methods as they are.
I think you have a few options here:
Create a view in your database, which has the column fullName. Then change your model to use the view.
Create a computed column fullName so that on insert if will use the values given from firstName and lastName.
Use Laravel's Collection class. This class provides a sortBy method which you can use an attributes.
If you go with option 2, first define an attribute:
public function getFullNameAttribute()
{
return $this->firstName . $this->lastName;
}
Then using Laravel's Collection:
$items = Model::all()->sortBy('FullName');
Note: The default option for sortBy is ascending, so if you wish to sort descending:
$items = Model::all()->sortByDesc('FullName');
You can read more about accessors here: https://laravel.com/docs/5.7/eloquent-mutators#defining-an-accessor
I've solved the problem with this solution:
$sorted = User::get()
->sortBy('full_name') //appended attribute
->pluck('id')
->toArray();
$orderedIds = implode(',', $sorted);
$result = DB::table('user')
->orderByRaw(\DB::raw("FIELD(id, ".$orderedIds." )"))
->paginate(10);
I've appended fullName attribute to the model, to be used by sortBy.
With this solution I was able to use orderBy to order by an appended attribute of the model, exactly what I wanted to do. So yes, it is possible. And also I was able to use pagination. Thanks to all who tried to help.
$personas = Persona::select('*');
$personas = $personas->addSelect(DB::raw('concat(nombre,\' \',apellido1,\' \',apellido2) as fullname'))
->orderBy('fullname', 'ASC')->paginate(K_LINEAS_X_PAGINA);
I couldn't make it work without the select('*')

Pass specific id to model and take data from database using codeigniter?

My controller method like below
public function index($book_id) {
print_r($book_id);
}
I will get the id from view. View like below
I need to get specific row according id on model how can I do that if I use query in controller its not working
If I use like below in controller it gives something else as result
public function index($book_id) {
print_r($book_id);
$this->db->select('*');
$this->db->from('books')->where('book_id', $book_id);
$query = $this->db->get();
print_r($query);
}
but if I use same query in model with hard coded id for testing it gives the expected out put
Please help me with this
You don't need to include "/index" in anchor tag href as controller default method will be index if found. And "print_r($book_id)" should be "echo $book_id" as $book_id is variable not array.
Please try this code (either in model/controller):
$query = $this->db->get_where('books', array('book_id' => $book_id));
$result = $query->row_array();
print_r($result);

How to replace the value of field on another?

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;
}

codeigniter pass variable from controller to model

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.

Resources