CakePHP displayField usage - php

Can you tell me how to use CakePHP's displayField directive? I can not figure out how to use it.
So, in a model file, I have following code:
<?php
class Task extends AppModel {
var $name = 'Task';
var $displayField = 'projectName';
//The Associations below have been created with all possible keys, those that are not needed can be removed
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id',
'conditions' => '',
'fields' => '',
'order' => ''
...
How can I use this, to display field projectName in select form field?

So, you have Task belongsTo Project (FK: project_id). You want to make a project select box in tasks/add and tasks/edit views.
The problem is that the projects table doesn't have a field called name or title so the select box is empty. You wouldn't have any problems if there was a name or a title field, right?
Well, here's the solution, in the Project model add this:
var $displayField = 'projectName';
http://book.cakephp.org/view/71/Model-Attributes
So you were going in the right direction, just messed up the models a bit. I hope you understand it now ;]

You can basically do this (in controller):
$this->set('tasks', $this->Task->find('list'));
And make an input with name task_id, and make sure to force it to be a select box, so (in views):
echo $form->input('task_id', array('label' => 'youLabelHere', 'type' => 'select'));
displayField gives you a chance to choose which field will be used as a displayed option (one of) in the select box, if it's not provided in model the script will look for 'name' or 'title'.
If you wan't to display projects in the users forms (add, edit option) then your associations aren't right. Always make sure that there is an association (with good, conventional tables and keys names) between two model when you want to make a select box, Cake makes it as easy as can it gets.

Related

How to make(or idea) multiple language on dynamic menu on Laravel?

I would like to make dynamic menu on Laravel. The menu level will be stored in database. But my problem is that, these menus must able to switch to other language. So I'm not sure the laravel-localization is capable?. Below is my desire table.
menuid languageA(English) languageB languageC
1 menuname1 www xxx
2 menuname2 yyy zzz
Any advise or guidance would be greatly appreciated, Thanks
I love Spatie idea.
This package contains a trait to make Eloquent models translatable. Translations are stored as json. There is no extra table needed to hold them.
Table
id name
1 {'en' => 'Home', 'id' => 'Beranda'}
2 {'en' => 'About', 'id' => 'Tentang'}
Model
use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\HasTranslations;
class Menu extends Model
{
use HasTranslations;
public $translatable = ['name'];
}
Creating models
You can immediately set translations when creating a model. Here's an example:
$menu = Menu::create([
'name' => [
'en' => 'About',
'id' => 'Tentang'
],
]);
Getting a translation
The easiest way to get a translation for the current locale is to just get the property for the translated attribute.
$menu->name;
There is many ways two do that for example you can separate the data for two tables like
// Menus
id
link
sort_number
created_at
updated_at
// Menus languages
id
menu_id
title
language
created_at
updated_at
And then select them by relation.

CakePHP: Removing Redundancy In Database Tables

I am working on models using cakephp. I have two models, the post model; which contains a $hasMany relationship with the tags model. I want the tags name value to be a unique. This is to remove any data redundancy. I want to make it searchable via a AJAX like search box for the tags. I need to be able to automatically create the tags on the fly, but only if they have not already been created. How do i achieve this with CakePHP 2.6.1?
Example:
I have created two tables:
tags:
id name post_id
posts:
id title url content
In order to make sure that the name value of any tag is unique, simply add a validation rule to the Tag model for the name field. There is a specific isUnique validation rule. In your app/Model/Tag.php file, add this:
public $validate = array(
'name' => array(
'rule' => 'isUnique',
'message' => 'This tag already exists.'
)
);
That will cause any save operation on the Tag model with a duplicate tag name to fail with the error message you set in the model.
To make it ignore any duplicates, slightly change the way your save works. Add something like this to your Controller logic:
foreach ($this->request->data['Tags'] as $tagData) {
$this->Tag->set($tagData);
if ($this->Tag->validates()) {
$this->Tag->create();
$this->Tag->save($tagData);
}
}

Cakephp - Multiple Models for one Table

I have a User model that is used to store data on users of a dental examination system.
Typically, three types of users will exist: Admininistrator, Location Manager and Examiner.
It seems to have become necessary to treat these three roles as seperate models in my application (imagine how I'd have a different view for each role with different options etc... It's a nightmare).
How would I go about setting up the relationships in each Model.
My first thought is:
//Administrator Model
class Administrator extends User {
$name = 'Administrator';
$table = 'User';
$belongsTo = array(
'User' => array(
'className' => 'User',
'conditions' => array('User.role' => 'administrator'),
)
);
}
And then the User model will reference this one using a hasMany? In terms of CakePHP convention, how would one actually model this accurately?
Also, would this model extend the User model or the AppModel?
Of course you can create different models using the same table name. To do so, link each model with specific table with $useTable property (not $table):
class Administrator extends AppModel {
public $useTable = 'User';
}
But I don't know any CakePHP model property which will allow you to filter data returned when fetching results... You can only write your own conditions when linking model with another one, for example:
class SomeOtherModel extends AppModel {
public $hasMany = array(
'Administrator' => array(
'className' => 'Administrator',
'conditions' => array('Administrator.role' => 'administrator')
)
);
}
Which is not a good solution, because it will work only when executing queries for SomeOtherModel model.
You can also try applying an afterFind() callback to your Administrator / Examiner / ... models which will delete users of another role than needed, but of course it is not an efficient solution.
Another solution is just creating different database views which will contain only users of selected role (more on views - here). Then you can point each view to your CakePHP model, just as it was a normal database table.
But this solution is also not perfect. If you will have to add a new user role or change your table schema in the future, you will also have to modify your database views.

Select specific field of nested HABTM array

I have a tickets table, and a contacts table. A ticket can have many contacts.
I am paginating the tickets table, and want it to select specific fields including the first linked contact form the nested array. No matter what I try, I can't seem to figure this one out (or if it is even possible).
My code:
$this->paginate = array(<br>
'conditions' => array('status_id !=' => '3'),<br>
'limit'=>50,<br>
'fields'=>array('Ticket.title', 'Ticket.ticket_number', 'Priority.name', 'Status.name', 'Contact.0.full_name') <br>
);
(The Contact.0.full_name is causing it to fail. How can I make this work?)
So I can use this column with $this->Paginator->sort.
You cant call columns like this Contact.0.full_name CakePHP doesn't work like that. A valid field name is TableAlias.column_name
You cant use hasMany relation's children into sort operation.
To achieve similar functionality, You can drop hasMany and add hasOne to achieve the desired output. Because there's no schema changes in both relationship types.
$this->Ticket->unbindModel(array('hasMany' => array('Contact')));
$this->Ticket->bindModel(array('hasOne' => array('Contact')));
$this->paginate = array(
'conditions' => array('status_id !=' => '3'),
'limit'=>50,
'fields'=>array('Ticket.title', 'Ticket.ticket_number', 'Priority.name', 'Status.name', 'Contact.full_name')
);
Now you can use this column Contact.full_name for sorting purposes.

adding hasMany association causes find() to not work well

OK, I am a little bit lost...
I am pretty new to PHP, and I am trying to use CakePHP for my web-site.
My DB is composed of two tables:
users with user_id, name columns
copies with copy_id, copy_name, user_id (as foreign key to users) columns.
and I have the matching CakePHP elements:
User and Copy as a model
UserController as controller
I don't use a view since I just send the json from the controller.
I have added hasMany relation between the user model and the copy model see below.
var $hasMany = array(
'Copy' => array(
'className' => 'Friendship',
'foreignKey' => 'user_id'
)
);
Without the association every find() query on the users table works well, but after adding the hasMany to the model, the same find() queries on the users stop working (print_r doesn't show anything), and every find() query I am applying on the Copy model
$copy = $this->User->Copy->find('all', array(
'condition' => array('Copy.user_id' => '2')
));
ignores the condition part and just return the whole data base.
How can I debug the code execution? When I add debug($var) nothing happens.
I'm not an expert, but you can start with the following tips:
Try to follow the CakePHP database naming conventions. You don't have to, but it's so much easier to let the automagic happen... Change the primary keys in your tabel to 'id', e.g. users.user_is --> users.id, copies.copy_id -->copies.id.
Define a view, just for the sake of debugging. Pass whatever info from model to view with $this->set('users', $users); and display that in a <pre></pre> block
If this is your first php and/or CakePHP attempt, make sure you do at least the blog tutorial
Make CakePHP generate (bake) a working set of model/view/controllers for users and copies and examine the resulting code
There's good documentation about find: the multifunctional workhorseof all model data-retrieval functions
I think the main problem is this:
'condition' => array('Copy.user_id' => '2')
It should be "conditions".
Also, stick to the naming conventions. Thankfully Cake lets you override pretty much all its assumed names, but it's easier to just do what they expect by default.
The primary keys should be all named id
The controller should be pluralised: UsersController
First off, try as much as possible to follow CakePHP convention.
var $hasMany = array(
'Copy' => array(
'className' => 'Friendship',
'foreignKey' => 'user_id'
)
);
Your association name is 'Copy' which is a different table and model then on your classname, you have 'Friendship'.
Why not
var $hasMany = array(
'Copy' => array('className'=>'Copy')
);
or
var $hasMany = array(
'Friendship' => array('className'=>'Friendship')
);
or
var $hasMany = array(
'Copy' => array('className'=>'Copy'),
'Friendship' => array('className'=>'Friendship')
);
Also, check typo errors like conditions instead of condition
Your table name might be the problem too. I had a table named "Class" and that gave cake fits. I changed it to something like Myclass and it worked. Class was a reserved word and Copy might be one too.

Categories