Laravel inserting into 2 tables - javascript

i have 2 tables user and tn_user, table user is a table containing information to log in, i made it by tutorial from https://laravel.com/ so basically it was automatically created, while tn_user is a table that i make by myself
USER TABLE
in case u can't see the atribut are id, name, email, password that the important things, email and password in this table is used to logging in
TN_USER TABLE
the atribut are cn_id, cv_name, cv_email, cn_phone, cv_position, cv_address, cv_country, cv_username, cv_password, cv_privileges, those are the important thing
based on the form below i want to insert username and password into table user and the rest into table tn_user and how do i do that? im pretty new to laravel so not really quite understand how, usually i use CI
UserController.php
this is where the code i use to insert data
i use json response to parse the data and not quite sure how to insert data into 2 tables little help here
public function createOrEdit(){
//get current user
$currentUserId = Auth::user()->id;
$isUpdate = false;
$id = Input::get('id');
$user = new UserCompany;
if($id != ""){
$user = UserCompany::where('cn_id', '=', $id)->firstOrFail();
$user->cv_updated_by = $currentUserId;
$user->cv_updated_at = Carbon::now();
$isUpdate = true;
}else{
$user->cv_created_by = $currentUserId;
$user->cv_created_at = Carbon::now();
}
$user->cv_name = Input::get('name');
$user->cv_position = Input::get('position');
$user->cv_email = Input::get('email');
$user->cn_phone = Input::get('phone');
$user->cv_address = Input::get('address');
$user->cv_username = Input::get('username');
$user->cv_password = Input::get('password');
$user->cv_country = Input::get('country');
if($isUpdate){
UserCompany::where('cn_id','=',$id)->update(['cv_updated_by' => $user->cv_updated_by,
'cv_updated_at' => $user->cv_updated_at,
'cv_name' => $user->cv_name,
'cv_position' => $user->cv_position,
'cv_email' => $user->cv_email,
'cn_phone' => $user->cn_phone,
'cv_country' => $user->cv_country,
'cv_username' => $user->cv_username,
'cv_password' => $user->cv_password,
'cv_address' => $user->cv_address]);
}else{
$user->save();
}
$returnedData = UserCompany::all();
$response = array(
'content' => $returnedData,
'status' => 'success',
);
return Response::json($response);
}
UserCompany.php is my model but since im new im not really understand how to use relationship yet
<?php namespace Activity;
use Illuminate\Database\Eloquent\Model;
class UserCompany extends Model {
protected $table = 'tn_user';
public $timestamps = false;
protected $fillable = [
];
/*public function usercompany(){
return $this->belongsTo('Activity\user');
}*/
}

You should know that in the UserCompany class, by setting the fillable, It means you are setting table column which you want to alter, in this case tn_user table. So this means, by setting
protected $fillable = [];
It means, that you are making no table columns should undergo modification when you are using commands like;
$user_details->cv_name = Input::get('cv_name');
Okay, so the first thing that you should know is that when creating two tables i.e users and tn_users you should have a column which carries a value which relate the two tables, I suggest that you are to user id from the users table:
I have noticed that you have used cn_id to be a linker, but it is best if every table has its own incrementing id column and also in this case, its own link_id column
Let's say you are starting over:
Open the command prompt or Terminal and go to you laravel project folder directory and type: -$ php artisan make:model User -m and again -$ php artisan make:model UserDetail -m
What this will do is, create User and UserDetail, and adding the -m means its creating the migrations for the models associated which is create_users_table and create_user_details_table
From the create_users_table simply create the desired table columns as shown below:
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table){
$table->increments('id');
$table->integer('auth');
$table->string('username')->unique();
$table->string('email');
$table->string('password');
$table->boolean('online');
$table->string('lang', 2);
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
//
Schema::drop('users');
}
}
Now for the create_tn_users_table its kinda important, you should set which links with the users account so that suppose you delete the users, his credentials are also removed, but you can make it do otherwise if you want.
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTnUsersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('tn_users', function (Blueprint $table) {
$table->increments('id');
$table->string('full_name');
$table->string('username')->unique();
$table->integer('link_user_id')
->references('id')->on('users'); // Relationship btn table tn_users and users
$table->string('phone');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('tn_users');
}
}
Now go the command prompt or terminal and type -$ php artisan migrate to have the tables created.
Again on the command prompt or terminal type -$ php artisan make:controller UserController --resource and have the controller made together with its resources.
On the create() function inside the UserController, add the Request in as a parameter.
The functions is to be reached upon the submission of the form that you have created
namespace App\Http\Controllers;
use App\User;
use App\TnUser;
use ...
class UserController extends Controller{
public function create(Request $request){
$tn_user = new TnUser();
$user = new User();
$user->username = $request['username'];
$user->password = bcrypt($request['username']);
...
$user->save();
$tn_user->full_name = ucword(strtolower($request['full_name'));
$tn_user->link_user_id = $user->id; // uses the previously save id
$tn_user->phone = trim($request['phone']);
$th_user->save();
}
}
I hope I have answered you questions. Here are some helpful links to learn.
https://laravel.com/docs/5.1/migrations#creating-columns
https://laravel.com/docs/5.1/requests

You Create 2 objects
$user = new User()
$user->username = INPUT::get('username');
$user->password = $password // Hashed
$user->save();
$user_detail = new UserCompany() // Your detail table modal.
$user_detail->cv_name = Input::get('cv_name');
//etc
$user_detail->save()

Related

Laravel websocket wont trigger event from vue front end

I already have setup my websocket connection with pusher. I can fire events at the websocket admin and i can show the output of it via console.log. Now i created a new event that if the user adds new product, the table will be updated whenever who is viewing it. But it seems I can add data successfully but the table wont update to other user. Can someone know why my event is not working?
ProductsEvent.php
namespace App\Events;
//show only important imports
use Illuminate\Broadcasting\Channel;
use App\Product; //Import my model
class ProductsEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $product;
public function __construct(Product $product)
{
$this->product = $product;
}
public function broadcastOn()
{
return new Channel('Products');
}
}
ProductsControlller (store)
public function store(Request $request)
{
$product = new Product;
//some validation...
//broadcast(new ProductsEvent($product)); if i put it here i got No query results for model [App\Product].
$product->barcode = $request->barcode;
$product->product_name = $request->product_name;
$product->price = $request->price;
$product->quantity = 0;
$product->category = $request->category;
$product->supplier_id = $request->supplier;
$product->save();
broadcast(new ProductsEvent($product));
}
channels.php
Broadcast::channel('Products',function(){
return true;
});
and my vue component
created(){
//when i successfully created the data,
i will call getProducts to listen in the channel for DOM updates
Echo.join('Products')
.listen('ProductsEvent',(event)=>{
this.getProducts()
})
}
If i call broadcast before save in my controller, I got something like this
No query results for model [App\Product].
I uncomented the App\Providers\BroadcastServiceProvider::class, line in config.php in order for the broadcast to work.
I dont know why .join wont work but I used window.Echo.channel i doubt this is the right thing to do.
created(){
this.getProducts()
this.getSuppliers()
// Echo.join('Products')
// .listen('ProductsEvent',(event)=>{
// // this.products.push(event.products)
// this.getProducts()
// })
// .here(()=>{
// console.log('here')
// })
window.Echo.channel('Products').listen('ProductsEvent',(e)=>{
this.getProducts()
toastr.success('Product Updated')
})
}

How to get related record from the parent table

I have two tables. users is a parent and leaves is a child table.
Every user has more than one leave requests.
users.id is primary key and leaves.userID is foreign key.
I want to get related user's record with the every leave record.
Here is users model
import bookshelf from '../config/bookshelf';
const TABLE_NAME = 'users';
/**
* User model.
*/
class User extends bookshelf.Model {
/**
* Get table name.
*/
get tableName() {
return TABLE_NAME;
}
/**
* Table has timestamps.
*/
get hasTimestamps() {
return true;
}
verifyPassword(password) {
return this.get('password') === password;
}
}
export default User;
Here is leaves model
import bookshelf from '../config/bookshelf';
const TABLE_NAME = 'leaves';
/**
* Client model.
*/
class leaves extends bookshelf.Model {
/**
* Get table name.
*/
get tableName() {
return TABLE_NAME;
}
/**
* Table has timestamps.
*/
get hasTimestamps() {
return true;
}
verifyPassword(password) {
return this.get('password') === password;
}
}
export default leaves;
It is my code to fetch the leaves records.
leaves.forge()
.fetchAll()
.then(leaves => res.json({
error: false,
data: leaves.toJSON()
})
)
.catch(err => res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({
error: err
})
);
Unless absolutely necessary, I don't recommend performing such a function in your application code. What you are asking is very rudimentary in the data world, and your DBMS will be far more capable of processing such a request. No need to slow down your app with a request that should be off-loaded to the DBMS. It's what the DBMS is made for. Don't reinvent the wheel.
If your DBMS supports Views, then create a View to perform this function. You could also do this in a Stored Procedure. It is a very simple JOIN query that can be done in as few as 3 lines of SQL code. After you have the View, your app can read data from it just like any other table.

How to return data with date range with Laravel 5.2?

So what I am trying to do is produce a trial balance report. I have to get all chart of accounts(coas) and sum of its debit and sum of its credit between two dates. I have these tables in the database and these are their attributes
Client: id, name
Coas: id, name
Journal: id, description, date
Journal_details: id, journal_id, coa_id, debit, credit
I have already put their relationships in the model.
Client.php
public function coas()
{
return $this->belongsToMany('App\Coa');
}
public function journal(){
return $this->hasMany('App\Journal');
}
Coa.php
public function clients(){
return $this->belongsToMany('App\Client');
}
public function journals_details(){
return $this->hasMany('App\JournalDetails');
}
Journal.php
public function journal_details(){
return $this->hasMany('App\JournalDetails');
}
public function client(){
return $this->belongsTo('App\Client');
}
JournalDetails.php
public function journal(){
return $this->belongsTo('App\Journal');
}
public function coa()
{
return $this->belongsTo('App\Coa');
}
I'm trying to get all of the coas with journal details of a specific client, which I am already doing.
$trials = $client->coas()->with('journals_details')->get();
However, I am using a date range to select only those that belonged to specific date that is inputted. Here is my controller. I tried this but it doesn't work.
public function trial_balance_generate(Request $request)
{
$client = Client::find($request->client_id);
$start = \Carbon\Carbon::parse($request->from)->startOfDay();
$end = \Carbon\Carbon::parse($request->to)->endOfDay();
$data= $client->coas()->with('journals_details')->whereBetween('date',[$start,$end])->get();
return response()->json($data);
}
I know there is something wrong with how I get the data. I just don't know how to get all the coas and its details with the journal header that contains the date.
This is my javascript for getting the date range.
$('.date').on('change', function() {
var from = $('#from').val();
var to = $('#to').val();
var client_id = $('.clientHidden').val();
$.ajax({
type : 'get',
url : '/user/'+client_id+'/reports/trialbalance/generate/',
dataType: 'json',
data : {
'from':from,
'to':to,
client_id':client_id
},
success:function(data){
$('td').remove();
for(var ctr = 0; ctr < data.length; ctr++)
{
$('#reportTbody').append()
'<tr><td>'+ data[ctr].name +'</td><td>{{$trial->journals_details->sum("debit")}}</td><td>{{$trial->journals_details->sum("credit")}}</td></tr>'+
}
}
});
});
Here is a photo of what I am trying to achieve https://imgur.com/a/IZvio That returns everything so no dates yet.
Is the date on your model a carbon instance? Otherwise they aren't comparable.
You can to set it as a Carbon instance on the model in the $date property:
protected $dates = [
'created_at',
'updated_at',
'date'
];
By doing this, you are overriding $datesso be sure to include created_atand updated_at (and deleted_atif you're using soft delete).
Documentation link
I think you need to debug the sql laravel executed and find out if it is as expected. The way to fetch executed sqls in laravel is use \DB::enableQueryLog():
In your controller method:
DB::enableQueryLog();
#your laravel query goes here
$laQuery = DB::getQueryLog();
#optionally disable the query log:
DB::disableQueryLog();
then you can print the sql executed before and check out if it is as expected!

How to validate POST data in Laravel 5.4?

I am testing an API in Laravel 5.4. I am now in the part of storing a record via API. I am having some issues on how to use Request::input() or Input::get() to validate POST data.
LessonsController.php
<?php
namespace App\Http\Controllers;
use App\Http\Requests;
use App\Lesson;
use App\Acme\Transformers\LessonTransformer;
//use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;
use App\Http\Controllers\Controller;
class LessonsController extends ApiController
{
/**
* #var Acme\Transformers\LessonTransformer
*/
protected $lessonTransformer;
function __construct(LessonTransformer $lessonTransformer)
{
$this->lessonTransformer = $lessonTransformer;
// $this->middleware('sentry.auth')->only('post'); // basic level of protection for creating a lession
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
* If we are using basic authentication, we should be using SSL
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store()
{
if( ! Input::get('title') || ! Input::get('body')){
return $this->setStatusCode(422)->respondWithError('Parameters failed validation for a lesson.');
}
Lesson::create($request->all());
return $this->respondCreated('Lesson successfully created.');
}
/**
* Display the specified resource.
*
* #return \Illuminate\Http\Response
*/
public function show($id)
{
$lesson = Lesson::find($id);
if( ! $lesson) {
return $this->respondNotFound('Lesson does not exist');
}
return $this->respond([
'data' => $this->lessonTransformer->transform($lesson)
]);
}
}
When I test my code above with POSTMAN using POST request. I am prompted with "{"error":"Parameters failed validation for a lesson.","status_code":422}"
.
I receive an error when I try to add data or I don't add data.
Do you have any idea how to correct my store() code? Any help is appreciated.
To validate form data in Laravel simply use "Laravel Form Requests". This allows you to validate your form data in request using some predefined validation rules of Laravel and if you need you can also create you custom laravel validation logic.
According to Laravel docs:
Form requests are custom request classes that contain validation logic.
It will simplify your validation logic, make your code neat and let you handle complex validations.
Try this, might help
public function store(Request $request)
{
if( ! $request->has('title') || ! $request->has('body')){
return $this->setStatusCode(422)->respondWithError('Parameters failed validation for a lesson.');
}
Lesson::create($request->all());
return $this->respondCreated('Lesson successfully created.');
}
The problem with my code above is that it does not have the $request var in the store() method.
In my code be below, the Request class is now injected into store method.
public function store(Request $request)
{
if (! $request->input('title') or ! $request->input('body') )
{
return $this->respondUnprocessableEntity('Parameters failed validation for a lesson.');
}
Lesson::create($request->all());
return $this->respondCreated('Lesson successfully created.');
}
Note: In postman, select x-www-form-urlencoded in Body

Function to add and remove a username

In my chat application project, I am trying to broadcast usernames to all the users whenever a new user is connected to a server. and remove a username whenever the user leaves the server. The below is the code which I have tried by going through tutorials. (please check the file.js file which is not showing the desired output)
Chat.cs (Working) --> Implements "Hub" class of SignalR
public class Chat : Hub
{
/* showing only related content */
static ConcurrentDictionary<string, User> _users = new ConcurrentDictionary<string, User>();
public override Task OnDisconnected()
{
var user = _users[Context.ConnectionId]; //user as ConnectionId
User removedUser; //new class object
_users.TryRemove(Context.ConnectionId, out removedUser);
return Clients.All.leave(user, DateTime.Now.ToString()); //dynamic expression
}
public void Joined()
{
User user = new User(Context.ConnectionId, Clients.Caller.username);
_users.TryAdd(user.ConnectionID, user);
Clients.All.joins(user.ConnectionID, user.Name, DateTime.Now); //dynamic expression
}
}
User.cs (Working)
public class User
{
public User(string ConnID, string Username)
{
Name = Username;
ConnectionID = ConnID;
}
public string Name { get; set; }
public string ConnectionID { get; set; }
}
file.js (not working)
var chatUsername = window.prompt("Enter Username:", ""); //username
var chat = $.connection.chat; //connection
//
chat.client.joins = function (ConnectionId, name, Date) {
ConnectionId = 1; /* given value to just test */
name = chatUsername;
};
chat.client.leave = function (user, date) {
user = ""; //making the string empty so that the disconnected user value will be lost.
};
//Here is the connection which calls the "Joined" function of the server (Chat.cs)
What should I write in file.js functions (joins and leave) so that I will get the desired result as I mentioned above. Before asking here, I have gone through this site which is doing the same but including additional javascript files(knockout.js and json) which I dont want to include.(bcos I am new to jquery).
In order to pass UserNames to the client you can take your dictionary and in your joined server side method you could change the SignalR line to be:
Clients.All.joins(_users.Values); //dynamic expression
Then the client version of joins would be:
chat.client.joins = function (users) {
for(var i = users.length - 1; i >= 0; i--) {
alert("User Name: " + users[i].Name + "\nUser Connection ID: " + users[i].ConnectionID);
}
};
Of course you can handle the user information differently than alerting it, but that's the gist of how to handle the data. Lastly, I'd recommend against passing down the connection ID to everyone because a third party could then easily hijack it.

Categories