I have the table 'posts' and 'users':
CREATE TABLE `posts` (
`id` int(11) unsigned NOT NULL auto_increment,
`name` varchar(255) default NULL,
`date` datetime default NULL,
`content` text,
`user_id` int(11) default NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL auto_increment,
`name` varchar(100) default NULL,
`email` varchar(150) default NULL,
`firstname` varchar(60) default NULL,
`lastname` varchar(60) default NULL,
PRIMARY KEY (`id`)
);
and the model classes:
<?php
class Post extends AppModel {
var $name = 'Post';
var $belongsTo = array(
'User'=>array(
'className'=>'User',
'foreignKey'=>'user_id',
'conditions'=>null,
'fields'=>null)
);
}
?>
<?php
class User extends AppModel {
var $name = 'User';
var $hasMany = array('Post');
}
?>
I am testing using var $scaffold.
However, after I add some users, I can only see an empty select menu in the add post page, which means the association is not working. I don't know what is wrong with my code. Please help me out.
Thank you very much!
See the below url:-
http://book.cakephp.org/1.3/view/1042/belongsTo
http://book.cakephp.org/1.3/view/1043/hasMany
//Try This for belongsTo :--
<?php
class Profile extends AppModel {
var $name = 'Profile';
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
)
);
}
?>
Or
<?php
class Profile extends AppModel {
var $name = 'Profile';
var $belongsTo = array('User');
}
?>
//For hasmany
<?php
class User extends AppModel {
var $name = 'User';
var $hasMany = array(
'Post' => array(
'className' => 'Post',
'foreignKey' => 'user_id',
'conditions' => array('Comment.status' => '1'),
'order' => 'Comment.created DESC',
'limit' => '5',
'dependent'=> true
)
);
}
?>
I am starting with cakePHP too and banged my head for some time before I realized that the "conventions" require the Model filename to be CamelCased.
Try using:
Post.php
User.php
otherwise it seems the models are totally ignored.
Related
I have two model user and project and user_id is stored in project table how to implement inner join to display user name for users tables and projects table all fields.
this is my model for defining association
// project model
class Project extends AppModel
{
public $actsAs = array('Containable');
public $hasOne= array('User');
}
//Query Is
$conetent= $this->Project->find('all',array('limit' => 3,'joins' => array(array('table' => 'users','alias' => 'User1','type' => 'INNER','conditions' => array('Project.user_id =User1.id')))));
Best to do using cakephp way.
Add following code to your project controller.
$conetent= $this->Project->find('all',array('limit' => 3,'contain' => array('User')));
What you're looking for is a belongsTo relationship. This way, when you do a find in the Projects controller, it will pull the appropriate record from the User table that the project belongs to. For example (using CakePHP 2.x)
Database Tables
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`firstname` varchar(32) DEFAULT NULL,
`lastname` varchar(32) DEFAULT NULL,
`email` varchar(96) DEFAULT NULL,
`password` varchar(64) DEFAULT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
`lastlogin` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `projects` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`name` varchar(32) DEFAULT NULL,
`description` varchar(32) DEFAULT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Users Controller
class UsersController extends AppController {
public $uses = array('User');
public function index() {
}
public function create() {
}
public function update() {
}
public function delete() {
}
}
Users Model
<?php
class User extends AppModel {
}
Projects Controller
<?php
class ProjectsController extends AppController {
public $uses = array('Project');
public $components = array('Paginator', 'RequestHandler');
public function index() {
$projects = $this->Project->find('all'));
}
}
Projects Model
<?php
class Project extends AppModel {
public $useTable = 'projects';
public $belongsTo = array('User');
}
The find in the projects controller should yield a result of something like this:
array(
(int) 0 => array(
'Project' => array(
'id' => '1',
'firstname' => 'John',
'lastname' => 'Smith',
'email' => 'john.smith#domain.tld',
'password' => '******',
'created' => '2016-10-06 00:00:00',
'modified' => '2016-10-06 00:00:00',
'lastlogin' => '2016-10-06 00:00:00'
),
'User' => array(
'id' => '1',
'user_id' => '1',
'name' => 'Project Name',
'description' => 'Project Description',
'created' => '2016-10-06 00:00:00',
'modified' => '2016-10-06 00:00:00'
)
)
)
I'm a beginner. I am using CakeDC ratings to make a star rating in my site. I managed to make it work but it is displaying radio choices.
And it show me error:
Undefined variable: item
and After pressing "Rate", the url changes to avis/post/view/redirect:1
I download the plugin and I unzip in C:\wamp\www\avis\app\Plugin
after I write CakePlugin::load('Ratings') in app/Config/bootstrap.php my database is
CREATE TABLE IF NOT EXISTS `posts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
CREATE TABLE IF NOT EXISTS `ratings` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_id` char(36) NOT NULL DEFAULT '',
`foreign_key` char(36) NOT NULL DEFAULT '',
`model` varchar(100) NOT NULL DEFAULT '',
`value` float NOT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `rating` (`user_id`,`model`,`foreign_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
in Post Model
public $hasMany = array(
'Rating' => array(
'className' => 'Rating',
'foreignKey' => 'foreign_key',
'dependent' => false,
)
);
in PostController
public $components = array('Paginator', 'Flash', 'Session','Ratings.Ratings');
public $actsAs = array('Ratings.Ratable');
public function index() {
$this->Post->recursive = 0;
$this->set('posts', $this->Paginator->paginate());
}
public function view($id = null) {
if (!$this->Post->exists($id)) {
throw new NotFoundException(__('Invalid post'));
}
$options = array('conditions' => array('Post.' . $this->Post->primaryKey => $id));
$this->set('post', $this->Post->find('first', $options));
}
in view
<h2><?php echo __('Post'); ?></h2>
<dl>
<dt><?php echo __('Id'); ?></dt>
<dd>
<?php echo h($post['Post']['id']); ?>
</dd>
<dt><?php echo __('Title'); ?></dt>
<dd>
<?php echo h($post['Post']['title']); ?>
</dd>
<?php
echo $this->Rating->display(array(
'item' => $post['Post']['id'],
'type' => 'radio',
'stars' => 5,
'value' => $item['rating'],
'createForm' => array(
'url' => array(
$this->passedArgs, 'rate' => $item['id'],
'redirect' => true
)
)
));
?>
</dl>
</div>
<script>
$('#ratingform').stars({
split:2,
cancelShow:false,
callback: function(ui, type, value) {
ui.$form.submit();
}
});
</script>
First Download Jquery Raty Js plugin From : https://github.com/wbotelhos/raty
Include js,css into your view
<div class="jrating" data-score="5"></div>
<script>
$('.jrating').raty({ score: function() {return $(this).attr('data-score');} });
</script>
This will create a hidden text field when you post the form
On controller :
$rating = $this->data['score'];
Now you can save rating in your table
My app works fine on my local server and I had to change the .htaccess files so that the cakephp app website would work on godaddy hosting, but now I found that some of the information is not retrieved from the tables in the live website which is weird because the same information is retrieved in my local app... I've lost hours searching for the cause but haven't found a possible explanation yet...
On this particular view I should get all the product prices doing this (only works locally):
public function index() {
$options = array('contain' => 'ProductPrice');
$this->set('products', $this->Product->find('all', $options));
}
The necessary models are loaded above in the controller with:
public $uses = array('ProductPrice', 'Product', 'MenuSection');
In the view I should get something like: (which happens in my local app)
products(array)
0(array)
Product(array)
ProductPrice(array)
1(array)
Product(array)
ProductPrice(array)
(and so on...)
but what I'm getting is: (which happens in my live app)
products(array)
0(array)
Product(array)
1(array)
Product(array)
(but no ProductPrice arrays...)
These are the table structures:
CREATE TABLE `product_prices` (
`id` tinyint(9) unsigned NOT NULL AUTO_INCREMENT,
`price` float(6,2) DEFAULT NULL,
`product_id` varchar(36) DEFAULT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=181 DEFAULT CHARSET=utf8;
CREATE TABLE `products` (
`id` int(9) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
`description` text,
`menu_nr` int(9) DEFAULT NULL,
`menu_section_id` int(9) DEFAULT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=96 DEFAULT CHARSET=utf8;
These are the models:
class ProductPrice extends AppModel {
public $name = 'ProductPrice';
public $useTable = 'product_prices';
public $actsAs = array('Containable');
public $belongsTo = array('Product');
public $validate = array(
'product_id' => array(
'rule' => 'notEmpty',
'message' => 'This is a required field and cannot be left empty.'
),
);
}
class Product extends AppModel {
public $name = 'Product';
public $actsAs = array('Containable');
public $hasMany = array(
'ProductPrice'
);
public $belongsTo = array(
'MenuSection',
);
public $validate = array(
'name' => array(
'rule-empty' => array(
'rule' => 'notEmpty',
'message' => 'This is a required field and cannot be left empty.'
),
'rule-unique' => array(
'rule' => 'isUnique',
'message' => 'There is already one product with that name.'
),
),
'menu_nr' => array(
'rule' => 'isUnique',
'message' => 'There is already one product with that Menu Item Nr.'
)
);
}
Could anyone help me find the cause? Where else should I look for? Any hints or best practice suggestions are welcome too, thanks.
I finally figured it out... it was a simple problem after all. My model names were called 'product.php' and 'product_prices.php' because I followed CakePHP blog example, but once I changed them to 'Product.php' and 'ProductPrice.php' (and so on...) they started working! I thought about this before but forgot to actually try it while in the middle of the mess. Cheers for trying to help
I have 4 models, Application , Accommodation, Invoice and InvoiceItem
Invoice, Application and Accommodation all hasMany InvoiceItem
InvoiceItem belongsTo Application, Accommodation and Invoice
The purpose of all this is so that the line items of an Invoice (which come from the InvoiceItem model) can be associated with either an Accommodation or an Application via the InvoiceItem.foreign_id depending on whether InvoiceItem.class is set as Accommodation or Application
From what I understand, this is known as a polymorphic association.
Unfortunately, when I do a $this->Invoice->find('all'); with recursive set to 3 (or set to -1 with the appropriate fields specified in containable) I get this MySQL error:
Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column
'InvoiceItem.class' in 'where clause'
SQL Query: SELECT `Application`.`id`, `Application`.`name`,
`Application`.`created`, `Application`.`updated` FROM `applications`
AS `Application` WHERE `Application`.`id` = 3786 AND
`InvoiceItem`.`class` = 'Application'
I don't understand why Cake would try to add InvoiceItem.class as a condition without creating a join for the InvoiceItem model.
Here are my models (note: I've cut down the number of fields in each for readability -- the Application and Accommodation models share very few similar fields in reality):
Accommodation Model
CREATE TABLE `accommodations` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created` datetime NOT NULL,
`updated` datetime NOT NULL,
PRIMARY KEY (`id`)
)
<?php
class Accommodation extends AppModel {
var $name = 'Accommodation';
var $hasMany = array(
'InvoiceItem' => array(
'className' => 'InvoiceItem',
'foreignKey' => 'foreign_id',
'conditions' => array('InvoiceItem.class' => 'Accommodation'),
)
);
}
?>
Application Model
CREATE TABLE `applications` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created` datetime NOT NULL,
`updated` datetime NOT NULL,
PRIMARY KEY (`id`)
)
<?php
class Application extends AppModel {
var $name = 'Application';
var $hasMany = array(
'InvoiceItem' => array(
'className' => 'InvoiceItem',
'foreignKey' => 'foreign_id',
'conditions' => array('InvoiceItem.class' => 'Application'),
)
);
}
?>
InvoiceItem model
CREATE TABLE IF NOT EXISTS `invoice_items` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`class` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
`foreign_id` int(10) unsigned NOT NULL,
`name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
)
<?php
class InvoiceItem extends AppModel {
var $name = 'InvoiceItem';
var $belongsTo = array(
'Accommodation' => array(
'foreignKey' => 'foreign_id',
'conditions' => array('InvoiceItem.class' => 'Accommodation')
),
'Application' => array(
'foreignKey' => 'foreign_id',
'conditions' => array('InvoiceItem.class' => 'Application')
),
'Invoice' => array(
'className' => 'Invoice',
'foreignKey' => 'invoice_id',
),
);
}
?>
Invoice model
CREATE TABLE IF NOT EXISTS `invoices` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
)
<?php
class Invoice extends AppModel {
var $name = 'Invoice';
var $hasMany = array(
'InvoiceItem' => array(
'className' => 'InvoiceItem'
'foreignKey' => 'invoice_id'
)
);
}
?>
I'm using CakePHP 2.4.0
class InvoiceItem extends AppModel,and bind no belongsTo.
class InvoiceItem extends AppModel {
var $name = 'InvoiceItem';
var $belongsTo = null
}
you can assign a suitable belongsTo to InvoiceItem at Runtime depend on content
$this->InvoiceItem->bindModel(array( 'belongsTo' => array(...) ) )
I'm having problems with a very simple ordering query. I have a Post model and a Tag model with a HABTM relationship and am trying to return a list of all posts with a particular tag assigned to them, ordered by the date the post is created.
$this->set('data', $this->Post->Tag->find('all', array(
'conditions' => array('Tag.id' => 1),
'contain' => array('Post' => array(
'order' => 'Post.created_date desc'
))
)));
While this returns the list of posts, it is not sorted by date.
With debugging on, it looks like the following query is being used:
SELECT `Post`.`id`, `Post`.`title`, `Post`.`created_date`, `PostsTag`.`post_id`, `PostsTag`.`tag_id`
FROM `database`.`posts` AS `Post`
JOIN `database`.`posts_tags` AS `PostsTag` ON (`PotsTag`.`tag_id` = 1 AND `PostsTag`.`post_id` = `Post`.`id`)
Code for posts model:
class Post extends AppModel {
public $name = 'Post';
public $hasAndBelongsToMany = array('Tag');
}
Code for tags model:
class Tag extends AppModel {
public $name = 'Tag';
public $hasAndBelongsToMany = array('Post');
}
Any help on the issue would be much appreciated - I'm using CakePHP 2.1. if it makes any difference.
What about defining the order attribute in your Tag Model?
Like e.g.
var $hasAndBelongsToMany = array(
'Post' => array(
'order' => 'Post.created_date'
)
);
I don't think that the "order" should be inside of "contain".
Try with:
$this->set('data', $this->Post->Tag->find('all', array(
'conditions' => array('Tag.id' => 1),
'contain' => array('Post'),
'order' => 'Post.created_date desc'
)));
or just:
$this->set('data', $this->Post->Tag->find('all', array(
'conditions' => array('Tag.id' => 1),
'order' => 'Post.created_date desc'
)));
Read this:-
http://www.jamesfairhurst.co.uk/posts/view/adding_tags_to_a_cakephp_app_hasAndBelongsToMany/
http://edivad.wordpress.com/2007/04/19/cakephp-hasandbelongstomany-habtm/
//try this
CREATE TABLE `tags` (
`id` int(11) NOT NULL auto_increment,
`tag` varchar(100) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `posts_tags` (
`post_id` int(11) NOT NULL,
`tag_id` int(11) NOT NULL
);
//Creating the Models and Relationships
class Tag extends AppModel {
var $name = 'Tag';
var $hasAndBelongsToMany = array('Post'=>array('className'=>'Post'));
}
class Post extends AppModel {
var $name = 'Post';
var $hasMany = array('Comment'=>array('className'=>'Comment'));
var $hasAndBelongsToMany = array('Tag'=>array('className'=>'Tag'));
}