Is it possible to insert records if not exists and delete records if not provided in Laravel and MySQL? - mysql

I have couple of checkboxes in my Laravel View lets say:
<input type="check" name="John">
<input type="check" name="Jane">
<input type="check" name="Mae">
<input type="check" name="Peter">
When I check all of the checkboxes, It will be save in the database like so:
#Participants Table
_____________
id | name
----+--------
1 | John
2 | jane
3 | Mae
4 | Peter
In my Log table:
#Log Table
_________________
id | activity
----+------------
1 | Added John as participant
2 | Added jane as participant
3 | Added Mae as participant
4 | Added Peter as participant
Now, my problem is when updating the participants.; In my Laravel view, I have all my checkbox selected based on the participants table data and let's say I unchecked John and Peter, When click update How can I add a history in my Log table that will display like this:
#Log Table
_________________
id | activity
----+------------
1 | Added John as participant
2 | Added jane as participant
3 | Added Mae as participant
4 | Added Peter as participant
5 | Removed John as participant
6 | Removed Peter as participant
and then in my Participants Table
#Participants Table
_____________
id | name
----+--------
2 | jane
3 | Mae
What I have done so far on Update:
$members = json_decode($request->projectmembers);
foreach ($members as $participantsitems) {
DB::beginTransaction();
DB::table('projects_participants')->upsert([
'project_id' => $request->projectid,
'task_id' => "",
'emp_number' => $participantsitems->id,
'created_by' => Auth::user()->emp_number,
'date_created' => Carbon::parse(Carbon::now()),
],
[
'project_id' => $request->projectid,
'emp_number' => $participantsitems->id,
]);
DB::commit();
$this->record_project_history("Added ".$participantsitems->name ." as participant",$request->projectid, "");
}
But what it did was insert if record does not exists and update if record exists. can anyone give me an Idea on how to solve my problem? Thank you!

There's no direct why to do that.
you should do this logic yourself.
But you there're some staff could help you (append to you method this snippet):
// after update/insert your new data you will need to delete other records
// using updated_at column to delete all records updated a second ago
// make sure to create a model for projects_participants and use it all over your code
ProjectsParticipant::where('project_id', $request->projectid)
->where('updated_at', '<=', Carbon::now()->subSecond())->delete();

Related

Extracting information from the database by choosing the most suitable one out of 3 conditions with PHP

I searched a lot on the internet about the subject I was going to ask, but unfortunately I could not find a useful result.
I have table named "POST"
postID | postDesc | postStatus | userID
_______________________________________
1 | Lorem... | public | 1
2 | Ipsum... | private | 1
3 | Dolor... | university | 1
I have another table named "Follow". In this table, I record who follows whom. For example:
followID | follow1 | follow2
____________________________
1 | 1 | 2
2 | 3 | 1
In my table named "Follow", the follower's id is in the follow1 column and the id of the followed person is in follow2. For you to understand this better, my table named "user" is as follows:
userID | userName | universityID
________________________________
1 | John | 1
2 | Crowell | 3
3 | Risav | 1
What I'm trying to do is if the data in the post table is public then anyone will be able to see it. If it is private, only followers will be able to see it. If it is a university, people with the same university ID will be able to see it.
For example, the user with id 1 wrote all the information in my "post" table. Now, if the user with 2 id numbers can view these posts, they will only be able to see the public post. Number 3 will be able to see both private posts and university posts. Because user number 3 follows user number 1 and also they both have the same university id.
I hope I explained in detail.
Code I wrote myself
SELECT * FROM post
INNER JOIN user ON post.userID=user.userID
WHERE post.postStatus='public' and post.postStatus='follower'
and EXISTS (SELECT * FROM follow where follow.follow2=user.userID and follow.follow1='some user id')"

Include all records associated with a record that has been found when search is used in Ruby on Rails

When trying to search for a record in rails I want to be able to return all records that are associated with that id. For instance, if I search for "John", I want to be able to return all records with the same fk.
Table 1
| id |
------
| 1 |
| 2 |
Table 2
| id | fk | name |
-------------------
| 1 | 1 | John |
| 2 | 1 | Doe |
| 3 | 2 | David |
| 4 | 2 | Smith |
SQL
Rails code in controller
includes(:table2).where('table2.name LIKE ?', "%#{search}%").references(:table2)
SQL returned
SELECT FROM `table1` LEFT OUTER JOIN `table2` ON `table2`.`fk` = `table1`.`id` WHERE (table2.name LIKE '%John%') AND `table1`.`id` IN (1)
This only returns the row where the search is found. How would I return the record with same fk?
table1 uses has_many :table2 and table2 uses belongs_to :table1
Thanks in advance!
UPDATE
index.html.erb just contains a form that submits the input to the controller and the controller runs the query and returns the result.
Expected input: John
Expected result:
| id | fk | name |
------------------
| 1 | 1 | John |
| 2 | 1 | Doe |
index.html.erb
<%= form_tag(categories_path, method: :get, :enforce_utf8 => false, id: "search-input") do %>
<%= text_field_tag :search, params[:search] %>
<button type="submit"></button>
<% end %>
categories_controller.rb
def index
#categories = Category.search(params[:search])
end
def Category.search(search)
includes(:category_type).where('category_type.name LIKE ?', "%#{search}%").references(:category_type)
end
I think what you are looking for is
CategoryType.where(fk: CategoryType.where('category_types.name LIKE ?', "%#{search}%").select(:fk))
This will generate the following sudo sql
SELECT
category_types.*
FROM
category_types
WHERE
category_types.fk IN (
SELECT
category_types.fk
FROM
category_types
WHERE
category_types.name LIKE '%JOHN%'
)
I solved this by doing a query that returns all of the records for the main table and then using their ids to return the records from the second table. I am thinking that may be another way to get all the results at once, but for now this will do.
#records = joins(:category_typed).select('categories.id').where('category_types.name LIKE ?, "%#{search}%")
where(id: #records.ids)

Laravel working out with multiple data in a column

I am working on a laravel base profiling system.
Example tables..
Person
id | Name | sports_id
1 | foo | 1,2
2 | bar | 2,3
3 | derp | 1,3
Sports
id | Name |
1 | basketball |
2 | volleyball |
3 | swimming |
Question:
How can I get all Name records from Person table, which have sports_id corresponding to value basketball only from Sports table?
Because I'm confused on how to execute the query such as above due to the Person table is not normalized.
Or
Is there a way to normalize the Person table, so that I can query properly?
You should really use many-to-many relationshsip here.
If for some reason you don't want to then use simple query:
User::where('sports_id', 2)->get();
You need create additional table for relationships called persons_sports. So your tables will looks like
persons [id, name]
sports [id, name]
persons_sports [person_id, sport_id]
Then you'll need add relationships to your models
// In Person class
public function sports()
{
return $this->hasMany(Sport::class)
}
Then you can search persons like
$sport_name = 'basketball';
$persons = Person::whereHas('sports', function ($query) use ($sport_name) {
$query->where('name', $sport_name);
})->get();

select2 multiple values store in database

I have successfully made a searchable drop down list,in which whenever I type something, data from database appears in drop down list, now I want to store these multiple values which are selected, in the database.
My code in controller
$temp = $model->package_item = $_POST['package_item'];
foreach($temp as $t)
{
$model->package_item=$t;
}
Package_item is the field in which searchable dropdown list is applied, and I am selecting multiple values, now how can I save these values in the database, so that I will have a single id, but against this id, package_item will have multiple values and the rest of the attributes will be repeated. Just like below.
id------package_item------package_description------package_name
1--------cake------------ very cheap-------------get one buy one free
1---------candles---------- very cheap-------------get one buy one free
1----------fireworks--------very cheap-------------get one buy one free
I am using select2 extension and here is the code for that in view file
$this->widget('ext.select2.ESelect2', array(
'name' => 'package_item',
'data' => CHtml::listData(Package::model()->findAll(), 'id', 'package_item'), //the whole available list
'htmlOptions' => array(
'placeholder' => ' search packge item?',
//'options' => $options, //the selected values
'multiple' => 'multiple',
'style'=>'width:530px',
),
));
Thanks in advance
My first answer was terribly misleading, so I deleted it and here and giving it another try.
You need to plan out your database tables. I'm making a suggestion here:
Table Items
itemId[PK]| name | price |...|
1 | cake | 5.00
2 | candles | 2.00
3 | fireworks | 10.00
4 | expensiveStuff | 50.00
Table Packages
packageId[PK] | name | description | price |
1 | full package | super cheap | 12.00
2 | epic package | best value for money | 55.00
Table PackagesItems
packageId[PK][FK]|itemId[PK][FK]|amount
1 | 1 | 1
1 | 2 | 1
1 | 3 | 1
2 | 1 | 2
2 | 2 | 2
2 | 3 | 3
2 | 4 | 1
You would then query your packages like this:
SELECT itemId FROM PackagesItems WHERE packageId = 1 for example
The keyword of this answer is COMPOSITE PRIMARY KEY, which you can see in the third table: there are two primary keys, which are also foreign keys that lead to the other tables.
With SQL JOINS, you could retrieve the information from the other two tables.
If you need more information, please narrow down the scope of your question. What exactly do you want to know?

DataMapper ORM relationships

table1(users)
|ID|name |type |
|1 |demo |admin |
|2 |demoX |client|
table2(visits)
|ID|admin_id|visitor_id|visit_date|...
|1 |1 |2 |2013-01-01|...
admin(fk)->users(id)
user(fk)->users(id)
simple scheduler project, it contain 2 tables.
1st (users) contain all users, 2nd table contain all bookings(visits).
to get all bookings of an admin i run Select * from visits where admin_id=$id;, and join
visitor info from users table.
........
so basically,
every admin can have many visit
visit must contain (ONE)admin and (ONE)visitor.
how can i setup this kind of relation in datamapper orm ?
This should do it:
class Users extends Datamapper
{
public $has_many = array(
'admin' => array(
'class' => 'users',
'other_field' => 'admin', // FK = admin_id
),
'visitor' => array(
'class' => 'users',
'other_field' => 'visitor', // FK = visitor_id
),
);
}
class Visits extends Datamapper
{
public $has_one = array(
'admin' => array(
'class' => 'users',
'join_self_as' => 'admin', // FK = admin_id
),
'visitor' => array(
'class' => 'users',
'join_self_as' => 'visitor', // FK = visitor_id
),
);
}
// then in your controller you can do:
$visit = new Visitor(1);
echo $visit->admin->name; // echo's 'demo';
echo $visit->visitor->name; // echo's 'demoX';
First of all I think, instead of having a table with admin_id and user_id (isn't helpful), you should have a separate table with users and privileges, then the table structure would be.
Users privileges
| id | user | privilege_id | | id | privilege |
| 1 | user1 | 1 | | 1 | user |
| 2 | admin1 | 2 | | 2 | admin |
Then when you are calling the user level within the application just:
SELECT privilege FROM privileges WHERE id = <privilege_id from users table which should already be set within your code> (MySQL)
you should ALWAYS try and set id's in your tables for this purpose, this will be the basis of your relationship data when your gathering data from another table, so in this example it will be the <id> field of the privileges table and the <privilege_id> of the users table.
From here you should be able to transfer this method across to Datamapper or codeigniter or whatever your misleading tags mean =]
if you need to SELECT a booking from a database, select the booking(make an additional table and append as below) and look for the times of the bookings where ((privilage_id == 1) && (privilage_id == 2)) this will look for the dates where there is both a admin and a user, instead of just looking at one user type you are looking at them all and also saving yourself some hassle by making the call to one column rather than several. also this way you can easily manage your tables as their names relate to there function.
Users privileges booking
| id | user | privilege_id | | id | privilege | | id | date | privilege_id |
| 1 | user1 | 1 | | 1 | user | | 1 |5/2/13| 1 |
| 2 | admin1 | 2 | | 2 | admin | | 2 |5/2/13| 2 |
so the MySQL would be SELECT date FROM booking WHERE ((privilege_id == 1) && (privilege_id == 2)) this will give you the results you would expect, if you need to sanitise your data to go into the tables then you would require two rows to be made in one database which would be done by a procedure like this (this example will use an imaginary filled booking form(and is done in PHP)):
if((isset($user) && (isset($usertype)) && (isset($usertypetwo)) && (isset($date)))
{
if(($usertype != $usertypetwo))
{
"Insert BLAH BLAH"
}
}
also remember using this method you will need to get the user type from the user table to get the privilege_id