Failed DB update requests with Laravel - mysql

After spending numerous hours on this and scouring the answers online, I'm royally stuck on a seemingly simple DB update with Laravel. Here is a (simplified) version of the flawed function in one of my controllers:
public function changeDetails(Request $request)
{
...
// It works to change member_id into another...
if (Request::input('recipient_id') != "null") {
DB::table('recipients')
->where('recipients.id','=',Request::input('recipient_id'))
->update([
'recipients.member_id' => Request::input('member_id')
]);
// ...but it won't let me change it to NULL.
} else {
DB::table('recipients')
->where('recipients.id','=',Request::input('recipient_id'))
->update([
'recipients.member_id' => null
]);
};
I initially thought that the issue had to do with the database or table, especially since the 'member_id' is a foreign key. However, I did two tests that prove otherwise. First, I made sure that the column is 'unsigned' and 'nullable'. Second, I manually inserted an integer into the "where" clause instead of the "Request::input('recipient_id')"... and it worked fine. I also confirmed that the value of "Request::input('recipient_id')" is indeed an integer, which should work within the appropriate column (that is 'bigint' type).
Any useful suggestions/observations? They would be greatly appreciated.

The code runs into else statement only when Request::input('recipient_id') is "null",
but your else statement also uses 'recipient_id' which is "null".
So your SQL statement will find a recipients where recipients.id = "null".
Obviously you don't have any "recipient_id" is "null", right?
...
else {
DB::table('recipients')
->where('recipients.id','=',Request::input('recipient_id')) // here the recipient_id is "null"
->update([
'recipients.member_id' => null
]);
};
...

Related

Yii 2 Active Query joinWith issue

I have a Active Record model "Event" with a hasOne relation 'getUser'.
Now, if I do :
$eventModels = Event::find()->joinWith([
'user' => function($q){
return $q;
}])->all();
----------------------------------------------------
foreach($eventModels as $m){
var_dump($m->user); //Everything good as $m->user returns the related user object
die('skdw');
}
But, if I add the "select" in the joinWith query, then related "user" object becomes null. Here is the issue :
$eventModels = Event::find()->joinWith([
'user' => function($q){
$q->select('email');// or, ['email'] or ['user.email'] etc. fields.
return $q;
}])->all();
----------------------------------------------------
foreach($eventModels as $m){
var_dump($m->user); // Returns NULL
die('skdw');
}
But, if I make it $q->select('*'), then $m->user working .
I believe it used to work in some previous versions of Yii 2 (Right now, I am working on Yii 2.0.9)
Is this expected behavior ? If yes, then what is the solution to fetch only some select fields for the related joinWith model ? I don't want to fetch all the related fields as some of the related fields might contain "TEXT" data type.
You need to select the primary key column for the relation for Yii to build them.
e.g. assuming your column is called id
$eventModels = Event::find()->joinWith(['user' => function($q){
$q->select(['id', 'email']);
}])->all();
Also, you don't need to return the $q variable.

Checking 2 Column for Duplicate

Currently, I have a system to hold main data
1) The email
2) The owner(user_id)
Every time someone uploads , I need to make sure that it doesn't not exist in the system. The catch is as I upload more and more, the amount of time taken to check for duplicate will grow steeply, just like the graph as shown.
Question
1) How do i check for duplicate efficiently?
2) I indexed the user_id and the email should I Fulltext it? I wont be reading the text but will be searching for it as a whole, so index is more logical?
3) I also read about creating Hash combining email&owner id then index the hash. Will it be a big difference from the current method?
4) Last method i thought of was to create a primary key for both email and user_id , once again idk how the performance would turn out.
Please advice.
Code
$exist = DB::table('contact')->where('email', $row['email'])->where('user_id', $user_id)->count();
if($exist < 1){
DB::table('contact')->insert(
['email' => $row['email'], 'name' => $row['name'], 'user_id' => $user_id]
);
}
Use Laravel Validator:
public function store(Request $request)
{
$this->validate($request, [
'user_id' => 'required|unique',
'email' => 'required|unique',
]);
//some logic here
}
Also you should use unique constraint in your database.

Save Model Values Without Null

Everytime i try attempt to update a row i receive an error which says "something is required". In codeigniter you can update rows without the need to set everything to null in the mysql tabel settings.
I just want to update one value not the entire row.
Is this possible?
if ($users->save() == false) {
echo "Umh, We can't update the user right now: \n";
foreach ($users->getMessages() as $message) {
echo $message, "<br>";
}
$this->flash->error("Error in updating information.");
$this->response->redirect('user/profile');
} else {
echo "Great, a new robot was saved successfully!";
$this->flash->success("Member has been updaed successfully.");
//$this->response->redirect('user/profile');
}
Your isseue happens because you have already filled table and not yet properly defined model. Phalcon is validating all fo model data BEFORE trying to save it. If you define your model with all defaults, skips etc. properly, updates will be fired on single columns as you wish.
If you have definitions, that does not allow nulls, but you need an empty or default value there anyway, you may want to use 'beforeCreate' actions in model implementations. Also if there are things with defaults to set on first insert, you may wanto to use skipAttributes method.
More information is in documentation: Working with Models. So far best bit over internet I've found.
Also, below is an example for nullable email column and NOT NULL DEFAULT '0' 'skipped' column from my working code:
public function initialize() {
$this->skipAttributesOnCreate(['skipped']);
}
public function validation()
{
if($this->email !== null) {
$this->validate(
new Email(
array(
'field' => 'email',
'required' => true,
)
)
);
if ($this->validationHasFailed() == true) {
return false;
}
}
}
You do want errors of "something is required". All you're missing are just proper implementations of defaults over models. Once you get used to those mechanics, you should find them easy to handle and with more pros than cons.
What you are doing is called an insert. To set a column to a different value in a pre-existing row is called an update.
The latter is flexible, the former in not.
I highly recommend not treating a database like this is what i feel like
Put all the data in. Null is your enemy

Cakephp find OR condition not working

I am looking to display coupons that haven't expired yet and coupons that do not expire at all. Here is my cakephp code:
public function coupons() {
$this->paginate['Coupon']=array(
'limit'=>9,
'order'=>'RAND()',
'OR'=>array(
'expires' =>0,
'Coupon.end_date >'=>date('Y-m-d')
)
);
$c=$this->paginate('Coupon');
$this->set('allcoupons', $c);
}
Everything works correctly EXCEPT for coupons that have expired. They still show up in my results. I have a test record that expires before today, yet it still shows up in my results. Is my 'OR' condition written incorrectly?
never mind. I figured it out. You have to encapsulate the 'or' behind 'conditions', like so:
public function coupons() {
$this->paginate['Coupon']=array(
'limit'=>9,
'order'=>'RAND()',
'conditions'=>array(
'OR'=>array(
'expires' =>0,
'Coupon.end_date >'=>date('Y-m-d')
))
);
$c=$this->paginate('Coupon');
$this->set('allcoupons', $c);
}

EF4.1 Eager loaded linked objects are returned null

Can anyone explain why a Company is returned but Company.CompanyServices is null (even though I've created one in the test)?
public List<Company> GetContactCompanies(int contactId)
{
var query = (
from directorCompany in ctx.CompanyDirectors
.Where(d => d.ContactAddress.Contact.Id == contactId)
.Include(d => d.Company.CompanyServices)
select directorCompany.Company
).OrderBy(c => c.CompanyName).Distinct();
return query.ToList();
}
Note substituting the Include for .Include("Company.CompanyServices") has no effect
Is the Company.CompanyServices property marked as virtual? Check out ScottGu's blog on entity framework, where he creates POCO classes with one to many relationships he marks the collection properties as virtual.
When I first started using EF 4, that had me stumped for quite a while.
Obviously I can't see your entity classes so this may be a moot point!
Found an answer that's not wholly inuitive, but it works which is the main thing.
Happy to see one that plays on the original query...
var query = (
from directorCompany in ctx.CompanyDirectors
.Where(d => d.ContactAddress.Contact.Id == contactId)
select directorCompany.Company
).OrderBy(c => c.CompanyName).Distinct();
return query.Include(c => c.CompanyServices).ToList();