codeigniter 3.1.7 query result returning boolean instead of result_array or result_object - codeigniter

I have been having an issue with a database query returning a boolean instead of result_array() or result_object. This seems very convoluted.
Below is the normal core query that is supposed to return a result:
$query = $this->db->query('MY_QUERY');
return $query->result_array();
To be more precise, the core code is generating a fatal_error when I use form validation from the core library to validate the is_unique $this->input
Fatal error: Call to a member function num_rows() on boolean in
C:\xampp\htdocs\MY_PROJECT\system\libraries\Form_validation.php on line 1122

Boolean usually means the query returned false. As you are specifying form validation is unique function - check that the table is spelled correctly and exists and that the corresponding field/column is spelled correctly and exists.
The proper syntax for the is unique function as a pipe separated rule is is_unique[table.fieldname]
The form validation is unique function doesn't check if the result object returns true or false it just immediately runs num rows on the result which will result in this error message if the query failed.
If after having checked that your inputs are correct (table and column names) and you are still receiving an error - turn on db debug in the config. This should provide more context to you as to why it is failing.

Related

Trying to get property 'stock_name' of non-object error while inserting data

i am getting data using crawl and trying to insert into database. i get abbreviations of company name and have a command to get the full form of the abbreviations. it works fine if the company name already exists in companies table, and when the command handle is run new company name is also inserted and i can get the name from the table but cannot insert the name as it shows error. here is the code:
$data['symbol']=$es[1];
$name=DB::table('companies')
->select('stock_name')
->where('stock_symbol',$data['symbol']=$es[1])
->first();
if(!empty($name->stock_name)){
$data['company_name']= $name->stock_name;
}else{
\Artisan::call("company:handle");
$name=DB::table('companies')
->select('stock_name')
->where('stock_symbol',$data['symbol']=$es[1])
->first();
$data['company_name']= $name->stock_name;
}
You can resolve it by doing
//...
$data['company_name']= $name->stock_name ?? '';
//...
Null coalescing (??) is a new operator introduced in PHP 7. This
operator returns its first operand if it is set and not NULL.
Otherwise it will return its second operand.

Fetch the value of a given column in Eloquent

I am trying to get the value of a single column using Eloquent:
MyModel::where('field', 'foo')->get(['id']); // returns [{"id":1}]
MyModel::where('field', 'foo')->select('id')->first() // returns {"id":1}
However, I am getting anything but the value 1. How can get that 1?
NOTE: It is possible that the record with field of foo does not exist in the table!
EDIT
I am ideally looking for a single statement that either returns the value (e.g. 1) or fails with a '' or null or other. To give you some more context, this is actually used in Validator::make in one of the rules:
'input' => 'exists:table,some_field,id,' . my_query_above...
EDIT 2
Using Adiasz's answer, I found that MyModel::where('field', 'foo')->value('id') does exactly what I need: returns an integer value or an empty string (when failed).
Laravel is intuitive framework... if you want value just call value() method.
MyModel::find(PK)->value('id');
MyModel::where('field', 'foo')->first()->value('id');
You're using the Eloquent query builder, so by default, it'll return an Eloquent model with only the value you wish.
The method you're looking for is pluck() which exists in the normal query builder (of which the Eloquent one extends) so your code should look as follows:
MyModel::where('field', 'foo')->pluck('id'); // returns [1]
The value() method that is being used in the other answers is an Eloquent model method. Using that means that the framework queries the database, hydrates the model and then returns only that value. You can save yourself a few keystrokes and few CPU cycles by using pluck() and have it handled simply in one query.

Eloquent Collections Where Condition

I want to get alternative products pictures.
dd($alternativeProduct->pictures);
When die and dump i get this result.
I need to get only the picture which is main. If main equals to 1. It is main picture.
When I write
dd($alternativeProduct->pictures->where('main', 1))
I got an empty array.
Here is my relation with Product and Picture relation
public function pictures(){
return $this->hasMany('App\Models\ProductPicture');
}
What can i do ?
The where method in a collection has three parameters: $key, $value and $strict, the last one defaults to true if not passed when calling the method. When $strict is true the comparison is done via === which does not do type coercion, meaning "1" === 1 is false.
From your dump data, I can see that "main" => "1" which means it's a string and you're passing an integer 1 to the where method, resulting in what I described above as a false condition and returning an empty result set. You can fix that by disabling strict comparison:
$alternativeProduct->pictures->where('main', 1, false);
// or the equivalent helper whereLoose
$alternativeProduct->pictures->whereLoose('main', 1);
Or passing a string as the value:
$alternativeProduct->pictures->where('main', "1");
That being said, if that's the only place you're using that collection in that request's context, I suggest that you filter the results at the database level, not after they are fetched, like so:
$alternativeProduct->pictures()->where('main', 1)->get();
Accessing the relations as a method ->pictures(), instead of as a property ->pictures, will return a Query Builder instance that allows you to add conditions to the database query and only fetch the actual items you need from the database, instead of fetching them all and filtering them out afterwards.
You may want to use whereLoose instead:
dd($alternativeProduct->pictures->whereLoose('main', 1))
From the Laravel docs:
The where method uses strict comparisons when checking item values. Use the whereLoose method to filter using "loose" comparisons.

Error when retrieving and updating data from database in Codeigniter

In my application controller, I have a method transaction_reimburse() that receives ids as POST string values. The method's function is to get all transactions that match the ids from the database, and update them accordingly.
Controller method:
public function transaction_reimburse() {
$reimburse = array('reimburse' => 1);
$transactions = $this->Transaction_model->get_these_ids($this->input->post('ids'));
$this->Transaction_model->reimburse_these($transactions, $reimburse);
}
Model method:
function get_these_ids($ids) {
$this->db->select('tbl_user.name as uname, tbl_transactions.participant_id as pid, tbl_transactions.card_number as card_no, tbl_transactions.group as ugroup, tbl_toilet.name as utoilet, tbl_transactions.amount_paid as u_amount, tbl_transactions.toilet_price as t_price, tbl_transactions.reimburse_amount as r_amount, tbl_transactions.details as u_details');
$this->db->from('tbl_transactions');
$this->db->join('tbl_user', 'tbl_user.participant_id = tbl_transactions.participant_id', 'left');
$this->db->join('tbl_toilet', 'tbl_toilet.toilet_code = tbl_transactions.toilet_code', 'left');
$this->db->where("tbl_transactions.id IN (". $ids .")");
return $this->db->get();
}
Model method:
function reimburse_these($transactions, $reimburse) {
$this->db->select('tbl_user.name as uname, tbl_transactions.participant_id as pid, tbl_transactions.card_number as card_no, tbl_transactions.group as ugroup, tbl_toilet.name as utoilet, tbl_transactions.amount_paid as u_amount, tbl_transactions.toilet_price as t_price, tbl_transactions.reimburse_amount as r_amount, tbl_transactions.details as u_details');
$this->db->from('tbl_transactions');
$this->db->join('tbl_user', 'tbl_user.participant_id = tbl_transactions.participant_id', 'left');
$this->db->join('tbl_toilet', 'tbl_toilet.toilet_code = tbl_transactions.toilet_code', 'left');
$this->db->where("tbl_transactions.id IN (". $transactions .")");
$this->db->update($this->tbl_transaction, $reimburse);
}
However, I am getting the following error:
A PHP Error was encountered
Severity: 4096
Message: Object of class CI_DB_mysql_result could not be converted to string
Filename: models/transaction_model.php
Line Number: 450
A Database Error Occurred
Error Number: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1
UPDATE `tbl_transactions` SET `reimburse` = 1 WHERE `tbl_transactions`.`id` IN ()
Filename: C:\xampp\htdocs\ipa\system\database\DB_driver.php
Line Number: 330
What I need to know is why do I get these errors?
The errors mean that your $ids variable is not in a string format (meaning: 1,2,3,4. Its probably an array). To fix it, first find out what format it is on by using print_r($ids) or var_dump($ids). Once you know the format, use PHP functions(such as implode()) to transform it into strings.
IN is looking for a set in the format e.g. (1,2,3,4).
Either make your post values adopt the format 1,2,3,4 so that when the value is included into the query it's valid or if you're sending an array use a method in PHP such as implode(',',$array) to create the desired format for binding into the query..
I have reviewed your both function and found that in both function you put tbl_transactions.id in where clause and ids is passed from post and hence there is no need to call get_these_ids to get ids, you already have ids in post array and hence instead of transactions variable, just use $this->input->post('ids') for reimburse_these functions.
if you surely want to get tbl_transactions from get_these_ids function then you need to use group_concat with group by in query of get_these_ids function and just return that concated id in get_these_ids function then it will work.

ActiveRecord search returns 'Syntax error or access violation' error

In my Yii application, I have a model that represents siteconfig table and have four columns:
integer config_id,
string key,
string value,
string update_time.
I created a model using Gii (to ensure that I will not make any mistakes). I don't publish entire code here, cause this is 100% unmodified by me, standard model code generated by Gii. Since my problem is related to search, I only publish important part of generated code (the search() method):
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('config_id',$this->config_id);
$criteria->compare('key',$this->key,true);
$criteria->compare('value',$this->value,true);
$criteria->compare('update_time',$this->update_time,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
I'm trying to use generated model in normal Yii ActiveRecord search like that:
$etona = new SiteConfigurationRecord();
$crit = new CDbCriteria();
$crit->select = "value";
$crit->condition = "key=:key";
$crit->params = array(":key"=>"sitename");
$etona = $etona->find($crit);
But, instead of getting expected search results, a strange (for me) error occurs:
CDbCommand failed to execute the SQL statement: SQLSTATE[42000]:
Syntax error or access violation: 1064 You have an error in your SQL
syntax; check the manual that corresponds to your MySQL server version
for the right syntax to use near 'key='sitename' LIMIT 1' at line 1.
The SQL statement executed was: SELECT value FROM siteconfig t
WHERE key=:key LIMIT 1
Where did I go wrong?
You used key for column name, which is a reserved word in MySQL. Yii uses table alias in queries, but does not take any special care in case of reserverd word used as columns names. So, you have to take care of this by yourself.
For example:
$etona = new SiteConfigurationRecord();
$crit = new CDbCriteria();
$crit->select = "value";
$crit->condition = "t.key=:key"; // 't' is default alias
$crit->params = array(":key"=>"sitename");
$etona = $etona->find($crit);
This should solve your problem.
As #Dmitry explained, SQL doesn't allow you to use the column name key. The Yii call in the code in your answer works because Yii performs parameter binding automatically, using names other than reserved words for the parameters. And it also uses fully-qualified column names (prefixes all column name references with <tablename>., regardless of what invalid column name (reserved words) you pass the findByAttributes method.
now it works.. ^^
i just use this code...
$etona = SiteConfigurationRecord::model()->findByAttributes(array('key'=>'sitename'));
maybe i need to study activerecord more somehow...
but still i don't know why the code above doesn't work

Resources