Saving into 2 models with one form in Cakephp3 - save

I have 2 models : Users and Vendors model with relation : Vendors belongsto Users and Users hasMany Vendors.
The users table have following data :
Users table
The vendors have the following data : Vendors
The vendors table have a foreign key (user_id ) which is primary key in users table
I am trying to do vendor register. With that the data will be saved in both tables , (probaly will be saved in vendor table first and then user table ) . Here's is my code in VendorsController.php :
public function add()
{
$vendor = $this->Vendors->Users->newEntity();
if ($this->request->is('post')) {
$vendor = $this->Vendors->patchEntity($vendor, $this->request->data , ['associated' => ['Users']]);
if ($this->Vendors->save($vendor)) {
$this->Flash->success(__('The vendor has been saved.'));
// return $this->redirect(['acbbtion' => 'index']);
} else {
$this->Flash->error(__('The vendor could not be saved. Please, try again.'));
}
return $this->redirect(['controller'=>'listings','action' => 'add']);
}
$users = $this->Vendors->Users->find('list', ['limit' => 200]);
$this -> set(compact('vendors','users'));
$this->set('_serialize', ['vendor']);
However, this code is only save the data in vendors table but not user table.And user_id ( foreign key in vendors table will have value NULL) . How can I make it to save in user table also ?

Related

EF6 not loading child entities with alphanumeric IDs

Given the following tables:
SCHOOL
schoolid (int PK)
name
TEACHER
teacherId (int PK)
name, homeRoomId (fk varchar10)
subjectId (fk varchar10)
schoolid (FK int)
HOMEROOM
homeRoomId (PK varchar10)
roomNumber
active
SUBJECT
subjectId (PK varchar10)
name
active
I am using EF6 in an MVC app. I have lazy loading enabled. I am trying to return a list of all teachers for a given SchoolId and I need to include homeroom and subject data for each teacher.
A school contains many teachers, a teacher works for only one school, a teacher has only one homeroom and teachs only one subject. The homeroom and subject ids are varchars because they are pre-existing ids and look like: SUBJECT: A03, Math.
My code to load all teachers with homeroom and subject for a single schoolid:
public List<TeacherModel> GetTeachersBySchool(int schoolId)
{
List<TeacherModel> teachers = new List<TeacherModel>();
using (var db = new myDBEntities())
{
var list = db.Teacher.Where(a => a.SchoolId == schoolId).ToList();
foreach ( var s in list)
{
TeacherModel teacher = new TeacherModel()
{
TeacherId = s.TeacherId,
Name = s.Name,
HomeRoomId = s.HomeRoomId,
HomeRoomNumber = s.HomeRoom.RoomNumber,
SubjectId = s.SubjectId,
SubjectName = s.Subject.Name
};
teachers.Add(teacher);
}
return teachers;
}
}
The homeroom entity is loading but the Subject entity is null even through a sql query in the database returns one row for this teacher. Due to the null Subject entity, the query errors out as object reference not set to blah blah.
I have found that the problem seems to be when the SubjectId contains alpha characters. A couple examples of a subjectid are: "A03" or "1001023". The second entity will load, the first will not. I assume that even though the datatype is string/varchar EF6 is pulling out the numeric values and passing those as the id, so if the ID has alphas, it fails.
Does this jibe? How do I fix it? As a last resort I can add a surrogate key (INT Identity 1,1) for use with these entities but I'm hoping there is another way.

Return table records based on user role / table Join failing - linq query

I am building a MVC 5 (EF6) application that has a photographer table that's linked to the users table.
I identify a photographer by setting a role on the user account. The photographer table holds additional information not table. I have different types of users accessing the system.
I need to get the photographer table records based on the user being in the photographer role. I have the following solution but it comes back with the following error message when i try to access query result.
Unable to create a constant value of type 'Microsoft.AspNet.Identity.EntityFramework.IdentityUserRole'. Only primitive types or enumeration types are supported in this context.
var photogpraherRole = db.Roles.Single(r => r.Name == "photographer");
var users = photogpraherRole.Users.ToList();
var photographersList =
from photographer in db.Photographers
join user in users on photographer.User.Id equals user.UserId
orderby photographer.Priority
select photographer;
foreach (var photographer in photographersList)
{
var photographerName = photographer.User.FirstName;
}
After some research and the help from #Shawn Yan, this is the solution i came up with.
var photographerRole = db.Roles.SingleOrDefault(m => m.Name == "photographer");
var disabledRole = db.Roles.SingleOrDefault(m => m.Name == "disabled");
var users = db.Users.Where(m => m.Roles.All(r => r.RoleId == photographerRole.Id && r.RoleId != disabledRole.Id)).ToList();
var photographersList =
from photographer in db.Photographers.ToList()
join user in users on photographer.User.Id equals user.Id
where photographer.Location == booking.location.Location
orderby photographer.Priority
select photographer;
var photographers = photographersList.ToList();

How to get data from one table and then compare it with other table?

I have "Products table" with following fields
PID int,
product_name varchar(),
product_price int
"Cart table" with following fields
cart_ID
user_id
PID
So I want to display cart items of logged in user
For example if user_ID=100 is logged in , then only his cart items should be displayed to him, with all the product details.
Am using asp.net with entity framework
public ActionResult Cart()
{
Products pro = new Products();
Cart cart =new Cart();
var productID = db.cartDetails.Where(pid => pid.productId == cart.productId && cart.user_id == session["user_ID"]);
return View(db.productsDetails.Where(pid => pid.productId == productID));
}
Now problem arises, ProductID being var type I cannot compare it with pid => pid.productid.
What I want to do is first get all the product_id's of user from cart table by comparing uid_id (Logged in user) with user_id in cart table, then displaying product details of those product_id's from product Table. So obviously I need to store multiple product_id's,so that i can populate their data on the cart page.
The LINQ expression db.cartDetails.Where(pid=>pid.productId==cart.productId && cart.user_id==session["user_ID"]) would return a collection of cartDetails and not the productId. You must use select to fetch the columns you need, something like this
var productIDs = db.cartDetails
.Where(pid => pid.productId == cart.productId && cart.user_id == session["user_ID"])
.Select(cd => cd.productId)
.ToList();
This would return you a List of productIds. (If you wish to get only one productId, you could use SingleOrDefault or FirstOrDefault depending on your scenario like db.cartDetails.SingleOrDefault(pid => ...).productId).
Also note that you could have used int type for productId instead of using var if you were expecting an integer. Now you are getting a collection type IQueryable<cardDetails> being assigned to productId.
Next you cannot use an equality operator for the returned List anymore, you should check if this list contains the productId from productDetails, something like this:
return View(db.productsDetails.Where(pid => productIDs.Contains(pid.productId)));
Couldn't test this code, but the basic idea is here.
One last thing, consider using a join between the two tables: https://msdn.microsoft.com/en-us/library/bb311040.aspx
Did this and now my cart is working fine
public ActionResult Cart()
List<int> productIDs = new List<int>();
productIDs = db.cartDetails.Where(ch => ch.userId ==12).Select(cd => cd.productId).ToList() ;
List<Products> pDetails = new List<Products>();
for(int i=0;i<productIDs.Count;i++)
{
pDetails.Add(db.productsDetails.Find(productIDs[i]));
}
return View(pDetails);

Laravel Eloquent - include related columns in query results

Objective:
Return a composite response from my query, containing columns from both related models using Eloquent so that I can use Form::model to restore field values for User values AND Addresses values in my view. I want all the data in a single object and I don't want to use compact or otherwise manipulate the data if I don't have to.
Tables:
users (id, userWorkAddressID, ...)
addresses (ID, ...)
Models
User
public function address()
{
return $this->hasOne('Address', 'ID', 'userWorkAddressID');
}
Address
public function user()
{
return $this->belongsTo('User', 'id', 'userWorkAddressID');
}
Things I've tried
$user = User::find($id);
This just returns user data - no address data
$user = User::find($id)->address
This just returns the address for the user, but no user data
$user = User::with('address')->find($id);
This returns the user data, no address data
$user = User::with(array('address' => function($query){
$query->addSelect(array('id', 'addressLine1'));
}))->find($id);
This also returns only the user data, no address data
I could just use Fluent, but do I have to?
How can I use Eloquent to join those two tables and return a single object consisting of the fields I represent in my view?
First off your relations are wrong. Change both to:
public function address()
{
return $this->hasOne('Address', 'userWorkAddressID', 'ID');
}
Address
public function user()
{
return $this->belongsTo('User', 'userWorkAddressID', 'id');
}
then probably you will see the related model. Just remember to:
1 Eager load the related model: `$user = User::with('address')->find($someId);
2 use array notation for related model properties in the form: Form::model($user, ..) Form::text('address[city]', ...)

Find all instances of a type associated with another type

I have some classes that look like this:
class User {
boolean enabled
String username
}
class ExampleClass {
User firstUser
User secondUser
}
My end goal is to find all instances of User where enabled == true OR the instance of User is associated with ExampleClass.
Where this code is running I don't have access to the variable names firstUser or secondUser.
With that said, I need to be able to find all instance of User associated with ExampleClass, disregarding which variable (firstUser or secondUser) the association was made through. How do I do this?
UPDATE:
The best I can come up with is this method in my User domain class. I the example I gave above I have an ExampleClass which has multiple fields of the User type. In fact I have multiple classes with multiple fields of the User type. This is why I get the domain class from the object being passed in instead of just typing ExampleClass.
static List findAllEnabledOrAssociatedWith( Object obj = null ) {
if( obj?.id ) { // Make sure the object in question has been saved to database.
List list = []
obj.domainClass.getPersistentProperties().each {
if( it.getReferencedPropertyType() == User ) {
def propertyName = it.getName()
list += User.executeQuery( "SELECT DISTINCT ${propertyName} FROM ${obj.class.getSimpleName()} obj INNER JOIN obj.${propertyName} ${propertyName} WHERE obj =:obj", [ obj: obj ] )
}
}
list.unique()
return User.executeQuery( "SELECT DISTINCT users FROM User users WHERE users.enabled=true OR users IN(:list)", [ list: list ] )
} else {
return User.executeQuery( "SELECT DISTINCT users FROM User users WHERE users.enabled=true" )
}
}
def sql = '''
from
User u,
ExampleClass ex
where
u.enabled = 1 or (u = ex.firstUser or u = ex.secondUser)'''
def users = User.findAll(sql)

Resources