Save an id from a related model on save - cakephp

I'm sure there is a very simple solution to this, but the explanation is complex, so please do bear with me.
I have a registration form Registration::add() and it comprises of three sections.
The first is the Registration data, a number of fields.
The second is checkboxes from three related HABTM models, Role, Category and CategoryChild
Third is creating a record in User
My Registration model has a user_id and I need to save the generated User.id into that field.
I'm sure that I should be able to do this using the model relationships, as the User model saves the User.registration_id fine, but it doesn't seem to be writing into the Registration model.
Do I need to create another field in my add.ctp view so that the field is present in the $this->data->request array? I would much rather do this, than get embroiled in faffing with beforeSave() and afterSave().
So do I just need to create
$this->Form->input('Registration.user_id', array('type'=>'hidden'));
My relationships, for reference,
Registration hasOne User
Registration hasAndBelongsToMany Category
Registration hasAndBelongsToMany CategoryChild
Registration hasAndBelongsToMany Role
User hasOne Registration
I'm currently using saveAll($this->request->data) to save all my data, and it's managing to save everything except Registration.user_id

Your Relationships have
Registration hasOne User
However you have both a Registration.user_id and a User.registration_id implying that you need hasAndBelongsToMany relationship.
Just in case you're not using the Cake Baker to generate the models it is very useful.

Yes, something like this should work as per your question:
<?php echo $form->input('Registration.user_id',array('type'=>'hidden', 'value' => $user_id)); ?>
Hope it helps

Related

Django, relate User with another table

So I got the tables you can see in the image below:
.
What I would like to do is to create a relationship so that each user (of django auth_user) will be enrolled(or able to enrol) to exactly one "course" so that he will be able to see next events for his modules.
Do I have to create another table and place 2 foreign keys or this is a way to do it in 'php' and it's more simple with Django? I was suggested to create 'student' model inheriting from 'User' with extended behavior and one to many relationship on auth. I tried to do that but unfortunately had not results since I'm really new to Django & Python.
If every auth_user (or auth.User) will be or have the opportunity to be enrolled on a course I would create a 'user profile' model that has a 1-to-1 relationship with the django User model. You can store additional User data in this model, including what course they are enrolled on. See https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-the-existing-user-model for more details but here is an example:
class UserProfile(models.Model):
user = models.OneToOneField('auth.User')
course = models.ForeignKey('courseapp.Course', null=True)
You would probably need to create a signal that gets fired each time an auth.User object is saved, such that if it is the first time that User object has been saved, it automatically creates the UserProfile:
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from yourusersapp.models import UserProfile
def create_user_profile(sender, instance, created, **kwargs):
# Automatically creates a UserProfile on User creation.
if created:
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
When you query a User object, you can then reference the User object's profile like:
user_object.userprofile
You could then create a Course object and link the user_object indirectly via its UserProfile to that Course:
course = Course.objects.create(name='course_name', next_field='whatever')
user_profile = user_object.userprofile
userprofile.course = course
userprofile.save()
Now you have a user object with a UserProfile that is linked to only 1 course. Many users can be on the same course, but a user can only be on 1 course. You can also reference all users on a particular course like:
course = Course.objects.get(name='course_name')
course_users = course.userprofile_set.all()
HTH
I think that you can go about this one of two ways.
Extend the User model. 'Student' would probably be a good name for your new model. It would have a OneToOne relationship with 'User', and a ForeignKey relationship with 'Course'. It can store any other information that is applicable to students only. Documentation for how to do that can be found here https://docs.djangoproject.com/en/1.6/topics/auth/customizing/#extending-the-existing-user-model
Create a custom User model that has a ForeignKey relationship with Course. This approach is a bit more complicated, but yields a slightly cleaner end result. Documentation for that is here. https://docs.djangoproject.com/en/1.6/topics/auth/customizing/#substituting-a-custom-user-model
Sorry if it seems like I'm just sending you to the Django docs, but both of those sections are well written and should explain things pretty clearly. If you'd like to post another question with example code we can try and see why your original attempt at extending the User model didn't work. By the way, your "Student" model shouldn't have to inherit from the User model in order to extend it.

CakePHP How can I save many records in a link table at once for user - map - attributes?

I have three tables/models:
User(id)
Map(id, user_id, attribute_id)
Attribute (id, name)
Map belongsTo the others, the others hasMany Map.
I'd like the user (via user controller and user view) to create many links to associations at once. How can I do this, assuming that the user forms (add/edit) have 10 attribute fields, all linking to the same table?
I'd need to save up to 10 records in Map in one go. To start with, I'm unsure what the field should be - create('Attribute.name')? Also, cake outputs the same input name to each input as they point to the same field - what's the best way to fix this?
I have already read the relevant documentation, but didn't get much from it.
Thanks!
You can use saveAssociated() method. Prepare an input array according to the instructions given in the link and directly use $this->User->saveAssociated($your_array, array('deep' => true));

CakePHP: Administrator model that can create other models

I have the following models: Students, Teachers, Administrator
What I want to do is have an Admin menu, where I can list all the students and teachers, create new, and edit them too.
What would be the best way to achieve this? Import the model into the admin controller?
As #Anh says, the most straight forward way is to have admin_ actions in the student and teacher controllers respectively. You can access any model from any controller. If you want to list teachers in the students controller or vice versa, you can do so.
By default, a controller only imports the model of the same name. If that model is associated with other models, you can access the other models through the association like $this->Student->Teacher.
If you're going to do this often in a controller, simply load the necessary models directly into the controller using the $uses property:
class StudentsController extends AppController {
public $uses = array('Student', 'Teacher');
}
Now you have both models available directly.
Use prefix routing. In the teacher controller, create actions for admin (admin_index(), admin_add(), etc.) that can add/edit/remove records of teachers. Same for student controller.
Edit: the controller is where you can manipulate a particular model (and related models). If you want both students and teachers on a certain page, are these 2 models related to each other? Wait, aren't they both Users of the website? So what you want is: Admins can CRUD Users, right? So you can have all users listed in admin/users/index page (What I want to show here is: a problem can sometimes lead to a new db design, because you realize what you actually want these models to be).
Either that, or you can make a quick and dirty fix by either: loadModel in a controller of your choice, or use $uses, or make an arbitrary relationship between Teacher and Student.

How to implement user-friends relationship in cakephp?

I am new to cakephp.
I am working on my Social network project.I am having users and friends relationship
concept.
I am having problem in sending friend request and accepting .....
I am not understanding how to start on this concept...
If anybody worked on such things then please help me..
You could make a new FriendRequest model.
Give this model belongTo User and hasOne Friend. Also, User hasMany FriendRequest Then, give the FriendRequest model a boolean field (cakePHP uses TINYINT(1) for boolean) to track acceptance.
Create a new FriendRequest record when a user sends a request.
List all FriendRequest records that a user has sent by searching for the ones the user hasMany
List all the FriendRequest records that are sent to a person by searching for all Friend belongTo User.
Change the acceptance field to TRUE when a User accepts the request.

Elegant way to store anonymous users with nick names in django?

I have a simple Post model in my django app:
class Post(models.Model):
category = models.CharField(max_length=10, choices=choices)
message = models.CharField(max_length=500)
user = models.ForeignKey(User, editable=False)
I'd like to implement the feature of having anonymous users create posts with nick names. Unfortunately django doesn't allow you to save an instance of AnonymousUser as a foreignkey to the Post class.
I was thinking of adding a "dummy" user record into the db that represents the anonymous user(id=0, or some negative number if possible) that would be used for all posts without a user. And if it is present a nullable name field would be used to represent the nickname of the anonymous user.
This solution seems a bit hacky to me. Is there any cleaner more effecient solution?
If you can identify new users by some session information, you could just create normal user accounts, pro forma so to speak - with a flag to identify them as volatile (this may lead to some regular maintenance cleanup).
If, during session lifetime, the user actually want to register, you can reuse the user account on your side and the user can keep all his data on his.
As #slacy commented and #Dominique answered; instead of rolling your own take a look at existing projects, e.g. this:
http://www.stereoplex.com/blog/introducing-django-lazysignup
Not tested , but this can help:
https://github.com/danfairs/django-lazysignup
You can add blank=True and null=True to User ForeignKey and set it to None, if user is anonymous. You just need to store the nickname somewhere.
I am new to Django. A friend told me not to use ForeignKey further stating that using CharField is ok. ForeignKey is slower than CharField, as it has some check for user info.

Resources