I have a context of registrations at conferences. A registration has only one step if is a free registration. If is a paid registration there are two steps.
The first step of the registration consists of the user fill in a registration form and after click in the "Store Registration" button the info is stored in database and the column "status" of the registratins table is stored always with value "I" (incomplete).
If is a free registration there are no additional steps.
But if its a paid registration there is another step. In this step 2 the user needs to pay the registration before the conference start date. After the payment of the registration the column "status" of the registrations table stays with value "C" (complete).
Doubt:
If is a paid registration, after the step1 is necessary to issue a proforma invoice to the user and after the step2, that is, after the payment is necessary to issue a invoice/receipt to the user.
My doubt is how to organize the database for this context of issue proformas and invoices. In each paid registration is necessary to issue first a proforma after the user click in the "Store registration" button and all registration info is stored in db and then an issue an invoice after the payment. Is necessary to have two models/tables "Invoices" and "Proformas" and each one has a 1 to 1 relationship with Registration table. Or its just necessary 1 table related to the Registration table?
For now, I created two tables Proforma and Invoice and the relationships of these tables with the Registration table is like below 1 to 1, but I dont know if its correct.
Tables structure:
registration columns: id, status, conference_id, user_that_did_registration
proformas: id, proforma_number, registration_id
invoices: id, invoice_number, registration_id
Relevant models for the question:
Registration Model:
class Registration extends Model
{
public function customer(){
return $this->belongsTo(User::class, 'user_that_did_registration', 'id');
}
public function participants(){
return $this->hasMany('App\Participant');
}
public function registration_types(){
return $this->belongsToMany('App\RegistrationType', 'registration_registration_types');
}
public function conference(){
return $this->belongsTo('App\conference');
}
public function proforma()
{
return $this->hasOne('App\Proforma');
}
public function invoice()
{
return $this->hasOne('App\Invoice');
}
}
Proforma model:
class Proforma extends Model
{
public function registration()
{
return $this->belongsTo('App\Registration');
}
}
Invoice model:
class Invoice extends Model
{
public function registration()
{
return $this->belongsTo('App\Registration');
}
}
Based on your description, your design looks pretty close. Since not all Registrations have Proformas or Invoices, it makes sense to have Proformas and Invoices in a separate table. I would only make one change - if the relationship between Proformas and Invoices is truly 1 to 1, then you can put all the fields in a single record:
Proformas
ID
Registration_ID
Proforma_Number
Invoice_Number
Related
I have three models: Payment, Booking and Customer. A payment relation belongs to the Booking model and the Booking model belongs to the Customer model.
I need to make a customer relation inside the Payment model, however, they are not related, the only relation between them is through the Booking model.
My code:
public function booking(){
return $this->belongsTo(Booking::class , 'payable_id' , 'id')->with('customer');
}
// what i need , i need to consume that booking function to get customer info
// something like this
public function customer(){
// consume the booking relation
// return customer info
}
Could you please advise me on the right approach?
The answer to that is a Has One Through or Has Many Through relationship, depending on your business model.
Class Payment {
public function customer()
{
return $this->hasOneThrough('Customer', 'Booking');
}
// or:
public function customers()
{
return $this->hasManyThrough('Customer', 'Booking');
}
}
Hope it helps.
Based on your question you want to get customer information through "booking" let's say it is your lookup table where a customer id and payment id fields exist.
It should look like this
ERD of table image
In your Booking Model you have should two functions
public function customer() {
return $this->belongsTo(Customer::class, 'cust_id', 'id');
}
public function payment() {
return $this->belongsTo(Payment::class, 'payable_id', 'id');
}
In both your Customer and Payment Models add
public function bookings() {
return $this->hasMany(Booking::class, '(cust_id or payable_id respectively)', 'id');
}
in case you want to access booking via customer/payment models as well.
Now with those relationships you can access both payment and customer by accessing booking.
e.g.
$customers = Booking::all()->with('customer');
$payments = Booking::all()->with('payment');
Now you can manipulate all other data for display and/or editing or whatever you need to do with it.
You can also now access a customer's data with all of his/her bookings and payments associated. Below code results a collection of payments based on c
$customer = Customer::find(1)->with('bookings')->first();
$payments = $customer->bookings->payment;
For more questions feel free to delve in to the Official Laravel documentations.
In answering your question I based it on this.
https://laravel.com/docs/5.8/eloquent-relationships
Hope I helped and cheers!
I'm building a platform where a user can sign up and add products to sell. Also another user can buy products listed. When a buyer place an order, i want it to be seen by a seller(user) who listed the product. Right now all users can see all orders even if they are not sellers.
I have no idea how to proceed but here is my
order function in product controller
//Orders View Function
public function viewOrders(){
$orders = Order::with('orders')->orderBy('id','Desc')->get();
return view('orders')->with(compact('orders'));
}
Any help will be appreciated.
Your viewOrders action should be hidden behind authentication process (obviously, user has to first sign in before he can view his orders). Once you do that (using auth middleware for it's route), Laravel can resolve authenticated user for you - you can simply hint it as a parameter of your viewOrders action:
public function viewOrders(User $user)
{
$orders = $user->orders()->orderBy('id', 'desc')->get();
return view('orders')->with(compact('orders'));
}
As you notice, here I've modified your query a little bit. Instead of selecting all orders we are now selecting them through authenticated user's relation to it's orders. Orders obviously belong to user, but through products (as an intermediate) - one user can have many products, one product can have many orders, thus one user can have many orders. In Laravel this kind of relationship between eloquent models is called HasManyThrough. Therefore you should declare it in your User model:
class User extends Model {
...
public function orders()
{
return $this->hasManyThrough(Order::class, Product::class);
}
}
Note that your Product will probably also have orders() relation, but it will be of HasMany type instead since it's a direct one without any intermediates.
Filter your query base on your needs
Example:
Model Relationship
public function orders(){
return $this->hasMany(Order::class);
}
public function getMyOrders(User $user){
$orders = Order::with('orders')->orderBy('id','Desc')->where('user_id','=', $user->id)->get();
return view('orders')->with(compact('orders'));
}
To get sellers Orders
public function getSellerOrders(User $user){
$products = Product::where('user_id', '=', $user->id)->get();
$orders = [];
foreach($products as $product){
array_merge($orders, $product->order);
}
return view('orders')->with(compact('orders'));
}
In your DB table for orders you are suggested to have 2 IDs, one which denotes Buyer and Other which denotes Seller, i.e., Whenever a user places an order, then it must be a buyer then insert it's(buyer) ID into buyer_id in Order's table, similarly the product_id for denoting produc from Products' Table should be there and from Product's Table you can get seller_id which is suggested to be there for denoting which seller owns a particular product. Insert seller_id into Order's Table and use it to your query as:
$seller = Order::where('seller_id',$variable_for_product_id)->with('orders')->get();
Do this for all sellers in your Order's Table
I think I got a little stuck and I just need someone to clarify things. So what I got is a user system which includes subscriptions for people to "subscribe" to their content (as you already know it from FB, Twitter, YT etc).
My database model looks like this:
Users
id
username
Subsccriptions
id
user_id
sub_id
Currently I have one model for Users and one Model for Subscriptions. The model from the user:
public function subscriptions()
{
return $this->hasMany('App\Subscription');
}
In comparison, my subscription object:
public function user()
{
return $this->belongsTo('App\User');
}
So in my personal opinion this is a 1:many relationship. If I call the user object with User->subscriptions()->get() I can get the subscription and it's sub id, so I know who THE CURRENT user has subscribed.
People told me the opposite and it's supposed to be a many-to-many relationship. Did I do something wrong? Can I automatically convert the sub_id into a user through relationships in Eloquent?
// EDIT:
Here is the current code to receive my subscribers for a user
public function index()
{
$subs = Auth::user()->subscriptions()->get()->all();
$submodels = [];
foreach($subs as $sub) {
array_push($submodels,User::find($sub->sub_id));
}
return view('home', [
'subscriptions' => $submodels
]);
}
}
I have three table,employees,allowances and emp_allowances
In employees
id
name
In allowances
id
title
amount
In emp_allowances
employees_id
allowances_id
amount
Model functions are, Employee
public function empAllowances() {
return $this->belongsToMany('App\Model\EmplAllowance', 'emp_allowances', 'employees_id', 'allowances_id');
}
Allowance
public function employees() {
return $this->belongsToMany('App\Model\Employee');
}
It is working here $emp->empAllowances()->sync([1]); but when I am following this method,I can not save amount.
How can I save employee allowance details with amount?
try
$emp->empAllowances()->sync([1 => ['amount' => 10]])
Search for Adding Pivot Data When Syncing here
I have a database schema in my laravel app. In that schema, there are three models - Boss, Employee & Review.
A Boss can have many employees. An Employee can have many bosses(we can consider bosses from previous jobs). An Employee can Review his/her Boss. Boss can't Review anyone, so only Employee can review.
Thus, there are these relationships -
Employee & Boss has many-to-many relationship
Employee & Review has one-to-many relationship ( one Employee can Review multiple Bosses, thus having multiple reviews from his/her side ).
As you can see there is no direct relationship between Boss & Review. But, the query is -
What are the reviews for Boss 'x'?
To answer this query in laravel, I first thought that it had 'hasManyThrough' relationship. But, 'hasManyThrough' works only when Boss & Employee have 'one-to-many' relationship. That is, when one Boss can have multiple Employee but not vice-versa.
So, my question is - Is there a relationship which is applicable in this scenario(like polymorphic etc.)? If yes, how to use it in laravel?
No need for that extra table with reviews.
Here's all you need - first the tables:
bosses: id, ...
employees: id, ...
boss_employee: id, boss_id, employee_id, review (nullable), ...
Then the models:
// Boss model
public function employees()
{
return $this->belongsToMany('Employee')->withPivot('review');
}
public function reviews()
{
return $this->hasMany('Review');
}
// Employee model
public function bosses()
{
return $this->belongsToMany('Boss')->withPivot('review');
}
public function reviews()
{
return $this->hasMany('Review');
}
// Review model
protected $table = 'boss_employee';
public function boss() // or eg. reviewed
{
return $this->belongsTo('Boss');
}
public function employee() // or eg. reviewer
{
return $this->belongsTo('Employee');
}
Now, with this setup you can do this:
// get boss and his review
$boss = $employee->bosses->first();
$review = $boss->pivot->review;
// get review for given boss of an employee
$review = $employee->reviews()->where('boss_id', $bossId)->first();
// get bosses with reviews
$bosses = Boss::whereHas('reviews', function ($q) {
$q->whereNotNull('review');
})->get();
// and so on and so forth
You can enhance your Review model by adding global scope so it returns only the rows from boss_employee table having not null review field. This would be pretty much the same as SoftDeletingScope, but the conditions need to be swapped - by default whereNotNull, instead of whereNull in the SoftDeletingScope.