i have a problem to do this :
public $hasOne = array(
'Friend' => array(
'className' => 'Friend',
'conditions' => array('Friend.friend_id' => $this->Auth->user('id))
)
);
and i have an error :
Fatal Error
Error: syntax error, unexpected T_VARIABLE
File: /Users/guillaumebaduel/Sites/app/Model/User.php
Line: 98
What is the problem?
How can i get ID in a model?
Thanks
in the constructor:
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
$this->hasOne = array(
'Friend' => array(
'className' => 'Friend',
'conditions' => array('Friend.friend_id' => AuthComponent::user('id))
)
);
}
Note that you need to use the model constructor here (basic OOP) and that you cannot just use a non-declared object dynamically. Only statically, and only because the user method allows you to do so.
Even though it would be cleaner to attach such non-stateless bindings at runtime instead of doing it even for non-logged-in users and others who dont need that.
Related
Actually in my scenario I am binding relations in model's constructor function. Actually I need to use a model attribute in my model relationship and Cakephp preventing using model attribute in default relationships. So I can't use
public $hasMany = array(
'ProductDetail' => array(
'className' => 'ProductDetail',
'conditions' => array(
'ProductDetail.language_id' => $this->languageId //Throws error
),
'dependent' => true
),
);
So I made a trick. I did bind model relations on model's __construct() function. Below is my code
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
$this->bindModel(array(
"hasMany" => array(
'ProductDetail' => array(
'className' => 'ProductDetail',
'dependent' => true,
'conditions' => array(
'ProductDetail.language_id' => $this->languageId //Doesn't throw an error
)
)
)
)
);
}
This trick works for me in each scenario. But when I delete a product, dependent model can't be deleted when I am binding relations under __construct() function. Is there any way to make this trick works or I need to trigger dependent functionality manually ?
After doing research I found that pass second parameter to false on bindModel function. Because this will make your on-the-fly binding last the duration of the request. So in that case Model::bindModel function looks like
$this->bindModel(array(
"hasMany" => array(
'ProductDetail' => array(
'className' => 'ProductDetail',
'dependent' => true,
'conditions' => array(
'ProductDetail.language_id' => $this->languageId
)
)
)
), false
);
this is the content of the autoload/global.php file :
return array(
'db' => array(
'driver' => 'Pdo',
'dsn' => 'mysql:dbname=web_builder;host=localhost',
'driver_options' => array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
),
),
'service_manager' => array(
'factories' => array(
'Zend\Db\Adapter\Adapter'
=> 'Zend\Db\Adapter\AdapterServiceFactory',
),
),
);
this is the content of the autoload/local.php file:
return array(
'db' => array(
'username' => 'DB_User_Name',
'password' => 'DB_Password',
,
); )
this is part of the content of module/Module.php :
namespace Application;
use Zend\Mvc\ModuleRouteListener;
use Zend\Mvc\MvcEvent;
use Zend\Db\Adapter\Adapter;
.........
public function getServiceConfig() {
return array(
'factories' => array(
'Application\Controller\UserController' => function($sm) {
$dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
$table = new Model\StickyNotesTable($dbAdapter);
return $table;
},
),
);
}
Here I really don't understand what this function do, I just copy pasted from an example. If you could explain me what does getServiceConfig function do, I will really appreaciate it.
Finally the controller content:
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Db\Adapter\Adapter;
use Zend\Db\TableGateway\AbstractTableGateway;
use Zend\Db\Sql\Select;
class UserController extends AbstractActionController{
public function __construct(Adapter $adapter) {
$this->adapter = $adapter;
}
public function loginAction(){
// here i just want to a simple select and yes I know queries will be executed
//in Model, but I want to here a simple query.
//For example in Codeigniter I can't do in model, controller, or view as well.
return new ViewModel();
}
The result of all this code is obviously an error:
Catchable fatal error: Argument 1 passed to Application\Controller\UserController::__construct() must be an instance of Zend\Db\Adapter\Adapter, none given, called in C:\xampp\htdocs\zf2\vendor\zendframework\zendframework\library\Zend\ServiceManager\AbstractPluginManager.php on line 170 and defined in C:\xampp\htdocs\zf2\module\Application\src\Application\Controller\UserController.php on line 21
Can someone post an answer to make this database or query stuff work ? thx
I'm trying to define the relations for a specific Model depending on environment variables.
Like this:
class Book extends AppModel {
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
if (Configure::read('prefix') == 'admin') {
$this->hasMany['Page'] = array(
// ...
'conditions' => array( /* all pages */ )
);
} else {
$this->hasMany['Page'] = array(
// ...
'conditions' => array( /* only public pages */ )
);
}
}
}
You could argue that I should apply these conditions in the query. But because I'm working with deeply nested relations I wanted to keep conditions centralised.
Now the problem that occurs is: if the Page model has relations to e.g. the Paragraph model and from the BookController I'm trying:
$this->Book->find('first', array(
'conditions' => array('Book.id'=>1),
'contain' => array('Page' => array('Paragraph'))
));
... CakePHP will tell me that Paragraph is not related to the Page model.
If I create the relation by defining a model attribute all goes well:
class Book extends AppModel {
public $hasMany = array(
'Page' => array(
// ...
)
);
}
Why is this? Do I need to manually establish those relations? Is my timing (__construct()) incorrect and should this be done elsewhere?
Kind regards,
Bart
Yes, your timing is incorrect. You should either apply these configuration options before invoking the parent constructor:
if (Configure::read('prefix') == 'admin') {
// ...
}
parent::__construct($id, $table, $ds);
or use Model::bindModel() instead which will create the necessary links:
$this->bindModel(
array('hasMany' => array(
'Page' => array(
// ...
'conditions' => array( /* ... */ )
)
)),
false
);
See also http://book.cakephp.org/...html#creating-and-destroying-associations-on-the-fly
I have question in cakephp model,
I want to add dynamic condition in var $hasMany keyword
I want to add condition like current user_id, i got user Id after my login.
var $hasMany = array(
"AskComment"=>array('limit'=>3),
'AskStatistic',
'AskContactsLink',
'AskStatistic',
'AskObject',
'AskLikes'
);
If you want to add dynamic condition in your model, then you might have to bind the model association-ship dynamically into your controller's code. Write the following code into your controller's method for which you want to impose some new condition on the existing/new associated models.
$this->PrimaryModel->bindModel(array('hasMany' => array(
'AskComment' => array(
'className' => 'AskComment',
'foreignKey' => 'primary_id',
'conditions' => array('AskComment.user_id' => $user_id)
)
)
));
Take a look at this link: Creating and destroying associations on the fly. This will surely help you to achieve the same.
I think its better to put your association in the construct function of your Model.
like this:
/**
* #see Model::__construct
*/
public function __construct($id = false, $table = null, $ds = null) {
public $hasMany = array(
'AskComment' => array(
'className' => 'AskComment',
'foreignKey' => 'primary_id',
'conditions' => array(
'AskComment.user_id' => $user_id,
),
),
);
}
I have the following model
class Comment extends AppModel {
var $useTable = "comments";
var $recursive = 1;
var $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'userID'
)
);
function bindCommentsToUser() {
$this->bindModel(
array('belongsTo' => array(
'User' => array(
'className' => 'User',
'foreignKey' => 'userID'
)
)
)
);
}
The belongsTo variable at the top does absolutely nothing, I just cannot get it to work.
To confirm that the binding exists, I created the lower function to do dynamic binding which works perfectly. There appears to be no difference between the two. Is there some mistake that I am making or is there some setting somewhere else that has to be set?
There should be the same in both cases. You may want to create a ticket at http://cakephp.lighthouseapp.com. If possible change 'userID' to 'user_id' as recommended Travis Lleu. That will work for sure.