Unable to insert id of user to another table laravel 8 livewire - laravel-8

I am unable to store user id of another user on my db. I have a messages table, where from_id,t_id and user_id are the foreign key of table users. I have models defined properly as well. The issue I am having is:
can't insert the user_id.
I can save everything else. when i do dd $this->id it shows the corret user id but when it comes to save them i can't.
I tried doing explode and it stopped showing those random values. it now gets the id however in below format: [{"id":3}]
: Invalid text representation: 7 ERROR: invalid input syntax for type bigint: "[{"id":3}]"
As you can see it's getting the user id when i get the values from authenticated user which is obvious.
My code :
public $messages, $sender;
public $users;
public $avatar;
protected $destination = '';
public $messageText;
public function mount($id)
{
$this->id = $id;
$this->avatar = DB::table('users')
->join('messages', 'users.id', '=', 'messages.user_id')
->select('users.id')
->where('users.id', '=', $this->id)->distinct()->get();
$this->destination = DB::table('users')
->join('messages', 'users.id', '=', 'messages.user_id')
->select('users.id')
->where('users.id', '=', $this->id)->first();
$this->users =
Message::latest()
->take(5)
->get()
->sortBy('id');
$this->messages = DB::table('users')
->join('messages', 'users.id', '=', 'messages.user_id')
->select('users.name', 'users.id', 'messages.message', 'messages.created_at')
->where('users.id', '=', $this->id)
->get();
// SELECT * FROM users AS u INNER JOIN messages AS m ON u.ID IN (m.senderID, m.recipientID) WHERE u.ID <> $userID GROUP BY u.ID ORDER BY m.sentAt DESC
}
public function render()
{
// $name = explode(' ', $this->avatar);
// dd($name);
return view(
'livewire.show',
[
'avatar' => $this->avatar,
'messages' => $this->messages,
'users' => $this->users,
]
)->layout('layouts.app');
}
public function sendMessage()
{
$name = explode(' ', $this->avatar);
// $this->validate(['messageText' => "required"]);
$message = new Message();
$message->from_id = Auth::user()->id;
$message->user_id = Auth::user()->id;
$message->to_id = $name[0]; // [{"id":3}]
$message->message = $this->messageText;
// dd($message);
$message->save();
$this->reset('messageText');
}
Error Message:

Related

Laravel 8 removing qoute on the sql

Hi i just wanna know if what i did wrong
this my function
public function fetchJobs(Request $request){
$id = (int)$request->input("id");
$jobs = DB::table('job')
->select('job.*')
->where('job.status', '=', 0)
->Where('application.applicant','=' ,null)
->leftJoin('application', function($join) use ($id)
{
$join->on('application.job', '=', 'job.id');
$join->on('application.applicant','=',$id);
})
->toSql();
return $jobs;
}
this is the result
select `job`.* from `job`
left join `application` on `application`.`job` = `job`.`id` and `application`.`applicant` = `39`
where `job`.`status` = 0 and `application`.`applicant` is null
the error of is that 39 has qoutes is there a way to remove the qoute?
i solved this by adding DB:raw()
public function fetchJobs(Request $request){
$id = (int)$request->input("id");
$jobs = DB::table('job')
->select('job.*')
->where('job.status', '=', 0)
->Where('application.applicant','=' ,null)
->leftJoin('application', function($join) use ($id)
{
$join->on('application.job', '=', 'job.id');
$join->on('application.applicant','=',DB::raw($id));
})
->get();
return $jobs;
}

How to convert Distinct Count SQL query into a Laravel Eloquent query

I would like to convert this SQL query into a laravel eloquent query. So I can create
SELECT
count(distinct article_id) as assigned
FROM
actions
WHERE
action_id = 1 and
set_id = 1
I can translate the query into a raw request which works
DB::table('actions')->select(DB::raw('count(DISTINCT article_id) as assigned'))
->where('action_id', 1)
->where('set_id', 1)
->get();
But I would like to figure out how to do it something like this
$sets = Set::withCount(['actions as assigned' => function ($q) {
$q->distinct()
->select('article_id')
->where('action_id', '=', 1);
}])->get();
or this
$sets = Set::withCount(['actions as assigned' => function ($q) {
$q->distinct('article_id')
->where('action_id', '=', 1);
}])->get();
Eventually I would like to have my Set model contain a scoped method like this
public function scopeWithAssignedCount($query){
$query->withCount(['actions as assigned' => function ($q) {
$q->distinct('article_id')
->where('action_id', '=', 1);
}])
}
So I can add multiple counts to a single call in my controller
$sets = Set::withAssignedCount()
->withUnassignedCount()
->where('palm' => $face)
->get();
Edited per comments
I would like to use something like the below with distinct records.
public function scopeWithAssignedCount($query)
{
$query->withCount(['actions as assigned' => function ($q) {
$q->where('action_id', 1);
}]);
}
Check this query
$count = Set::select('article_id as assigned');
if(!empty($action_id)){
$count = $count->where('action_id', $action_id);
}
if(!empty($set_id)){
$count = $count->where('set_id', $set_id);
}
$count = $count->distinct('article_id')->count('article_id');

Get the last message postgres

I'm using Laravel to build something like a chat, i'd like to get the last message from user X and Y:
I have this table called "messages"
id integer
receiver_id integer references user
sender_id integer references user
message text
created_at datetime
Here I have a the message, when and who send the message;
$user = JWTAuth::toUser();
$messages = DB::table("messages")
->select(DB::raw(
"least(sender_id, receiver_id) as user_1,
greatest(sender_id, receiver_id) as user_2,
max(created_at) as last_timestamp,
max(message) as message"))
->where("sender_id", $user->id)
->orWhere("receiver_id", $user->id)
->groupBy(DB::raw("least(sender_id, receiver_id), greatest(sender_id, receiver_id)"))
->orderBy("last_timestamp", "desc")
->get();
$message_info = array();
foreach($messages as $k => $m) {
$message_info[$k]['message'] = $m->message;
$message_info[$k]['last_message'] = $m->last_timestamp;
if($m->user_2 == $user->id){
$message_info[$k]['user_id'] = $m->user_1;
}else{
$message_info[$k]['user_id'] = $m->user_2;
}
}
Here I list the users that have messages
$listUserHaveMessage = [];
foreach ($messages as $message){
if($message->user_2 == $user->id){
$listUserHaveMessage[] = $message->user_1;
}else{
$listUserHaveMessage[] = $message->user_2;
}
}
And here the users that not have send messages
$notMessage = User::where("client_id",'=',$user->client_id)
->where("id","!=", $user->id)
->where("is_visible",'=', true)
->whereNotIn("id", $listUserHaveMessage)
->get();
foreach ($notMessage as $m){
$listUserNotHaveMessage[] = $m->id;
}
Now I make the merge of arrays and a query to get all users
$list_users = array_merge($listUserHaveMessage, $listUserNotHaveMessage);
$idsImploded = implode(',',$list_users);
$users = User::where("client_id",'=',$user->client_id)
->where("id","!=", $user->id)
->where("is_visible",'=', true)
->whereIn("id", $list_users)
->orderByRaw(DB::raw("position(id::text in '$idsImploded')"))
->get();
$outPut = array();
foreach($users as $k => $u){
$outPut['usuarios'][$k] = $u;
}
My question is:
How to merge the last message to User array??
There is a way to do it??
Thanks

CakePHP3 filtering based on custom rules

I have following schema:
User hasMany RegistrationState
RegistrationState belongsTo User
to its classic 1->M relation where user_id is in RegistrationState table.
RegistrationState has following attributes
id, user_id, state, created_at ... ( others are not relevant )
User can have more registration states for example:
Registration state -> 1, created -> 01-02-2017
Registration state -> 2, created -> 01-03-2017
Registration state -> 3, created -> 01-04-2017
Registration state -> 4, created -> 01-05-2017
Registration state -> 2, created -> 01-06-2017
Registration state -> 3, created -> 01-07-2017
I need to filter based on this 'state property', where the valid state is last one created.
Valid state for this example is 3, because its latest state.
Now, i have controler, and index method where i have
// push custom query for filtering to finder method
$this->paginate['finder'] = [
'clients' => ['q' => $this->request->query]
];
try {
$clients = $this->paginate( $this->Users );
} catch (\Exception $e) {
// redirect on main
return $this->redirect($this->here);
}
My finder method looks like this
public function findClients($query, array $options)
{
$opts = $query->getOptions()['q'];
if (!empty($opts['email'])) {
$query->andWhere(['email LIKE' => '%' . trim($opts['email']) . '%']);
}
if (!empty($opts['identity_num'])) {
$cn = $opts['identity_num'];
$query->matching('Identities', function ($query) use ($cn) {
$query->andWhere(['Identities.number' => $cn]);
});
}
// registration state
if (!empty($opts['reg_state'])) {
// WHAT SHOULD BE HERE???
}
return $query;
}
There is also another 1->M relation User -> Identity, but ( matching method ) but that works fine because number is always unique.
I can't resolve problem with registration states, how can I implement this kind of search in CakePHP3? ( i dont want to break pagination so i would like to solve this in finder method )
One of possible (dirty?) solutions to this is subquery ( INNER JOIN on RegistrationState )
// registration state
if (!empty($opts['reg_state'])) {
$conn = ConnectionManager::get('default');
$subquery = $conn->execute(
'SELECT uir.user_id ' .
'FROM registration_state uir ' .
'INNER JOIN ( ' .
'SELECT user_id, max(created) as m_created ' .
'FROM registration_state ' .
'GROUP BY user_id ' .
') muir ON uir.user_id = muir.user_id AND uir.created = muir.m_created AND uir.status = '
. intval( $opts['reg_state'])
);
$usersInStateIds = [];
// transform result of subquery to usable array
foreach( $subquery->fetchAll('assoc') as $r ) {
$usersInStateIds[] = intval( $r['user_id'] );
}
$query->matching('RegistrationState', function ($query) use ($usersInStateIds) {
return $query->andWhere(['RegistrationState.user_id IN' => $usersInStateIds]);
});
}

get values between two dates in silverstripe

i have added two date fields. i want to retrieve the data between those two table.PaymentDate and ChequePostedDate are two fields. so i need to get the rows between two dates.
simply search content have two date fields. i want to retrieve the rows(data) between those two dates
public function __construct($modelClass, $fields = null, $filters = null) {
$fields = new FieldList(array(
DateField::create('PaymentDate','Payment Date : from')
->setConfig('dateformat', 'yyyy-MM-dd')
->setConfig('showcalendar', true)
->setAttribute('placeholder','YYYY-MM-DD')
->setDescription(sprintf(
_t('FormField.Example', 'e.g. %s', 'Example format'),
Convert::raw2xml(Zend_Date::now()->toString('yyyy-MM-dd'))
)),
DateField::create('ChequePostedDate','cr Date : to')
->setConfig('dateformat', 'yyyy-MM-dd')
->setConfig('showcalendar', true)
->setAttribute('placeholder','YYYY-MM-DD')
->setDescription(sprintf(
_t('FormField.Example', 'e.g. %s', 'Example format'),
Convert::raw2xml(Zend_Date::now()->toString('yyyy-MM-dd'))
)),
));
$filters = array(
'PaymentDate' => new PartialMatchFilter('PaymentDate'),
'ChequePostedDate' => new PartialMatchFilter('ChequePostedDate'),
);
parent::__construct($modelClass, $fields, $filters);
}
public function getQuery($searchParams, $sort = false, $limit = false, $existingQuery = null) {
$dataList = parent::getQuery($searchParams, $sort, $limit, $existingQuery);
$params = is_object($searchParams) ? $searchParams->getVars() : $searchParams;
$query = $dataList->dataQuery();
if(!is_object($searchParams)) {
if (isset($params['PaymentDate'])&& $params['ChequePostedDate'] ) {
$query->where('`PaymentNote`.PaymentDate BETWEEN \''.$params['PaymentDate'].' \' AND \''.$params['ChequePostedDate'].'\'');
}
}
return $dataList->setDataQuery($query);
}
}
You can also use WithinRangeFilter something like the following, but you need to use the setMin(), setMax() methods as per this forum response: https://www.silverstripe.org/community/forums/form-questions/show/11685
public function getQuery($searchParams, $sort = false, $limit = false, $existingQuery = null) {
$dataList = parent::getQuery($searchParams, $sort, $limit, $existingQuery);
$params = is_object($searchParams) ? $searchParams->getVars() : $searchParams;
$query = $dataList->dataQuery();
if(!is_object($searchParams)) {
if (!empty($params['PaymentDate'] && !empty($params['ChequePostedDate'])) {
return $dataList->filter('PaymentDate:WithinRange', [$params['PaymentDate'], $params['ChequePostedDate']]);
}
}
return $dataList;
}
i solved it..
simply remove $filters
$filters = array(
// 'PaymentDate' => new PartialMatchFilter('PaymentDate'),
//'ChequePostedDate' => new PartialMatchFilter('ChequePostedDate'),
);
then it works