I have a simple problem but I can not find an answer anywhere - neither in the documentation nor in this forum.
In short - I have 2 models in Kohana 3 - Task and TaskType.
I would like to create a Task model in such a way that I can then refer to the field $ task-> task_type_id-> name.
Unfortunately, when you insert a record into the database, I get the answer:
"General error: 1364 Field 'task_type_id' does not have a default value"
When I add the task_type_id field as a normal field (in $ _table_columns), then I can not refer to the TaskType object in the view via $ task-> task_type_id-> name.
I do not know how to configure the model to save the relation to the database and be able to refer to it in the view.
Please help.
My models code:
class Model_Task extends ORM
{
protected $_table_name = 'task';
protected $_table_columns = array(
'id'=>array('data_type'=>'int','is_nullable'=>false),
'date' => array('data_type'=>'date','is_nullable'=>
'description'=>array('data_type'=>'varchar','is_nullable'=>true)
);
protected $_belongs_to = array(
'task_type_id' => array(
'model' => 'TaskType',
'foreign_key' => 'id'
)
);
}
class Model_TaskType extends ORM
{
protected $_table_name = 'task_type';
protected $_table_columns = array(
'id'=>array('data_type'=>'int','is_nullable'=>false),
'name' => array('data_type'=>'string','is_nullable'=>false)
);
}
Probably it should be:
class Model_Task extends ORM
{
protected $_table_name = 'task';
protected $_table_columns = array(
'id'=>array('data_type'=>'int','is_nullable'=>false),
'date' => array('data_type'=>'date','is_nullable'=>
'description'=>array('data_type'=>'varchar','is_nullable'=>true),
'task_type_id' => array('data_type'=>'int','is_nullable'=>false),
);
protected $_belongs_to = array(
'task_type' => array(
'model' => 'TaskType',
'foreign_key' => 'id'
)
);
}
class Model_TaskType extends ORM
{
protected $_table_name = 'task_type';
protected $_table_columns = array(
'id'=>array('data_type'=>'int','is_nullable'=>false),
'name' => array('data_type'=>'string','is_nullable'=>false)
);
}
and adding by $task->add('task_type', $task_type);
Related
I am using AutoMapper.
My source object is simple class
public class Source
{
public string FirstName { get; set; }
public string type{ get; set; }
}
My destination is a MS Dynamics CRM Entity ( I have generated the model using CrmSvctil) which contains an option set named type.
Following is my mapping
AutoMapper.Mapper.CreateMap<Source, Destination>()
.ForMember(dest => dest.type, opt => opt.MapFrom(src => src.type));
I am getting error is type mismatch
Basically my problem is
I don't know how to map string to an Option set value using AutoMapper
OptionSets are stored as OptionSetValues that have a Value Property of type Int, not Strings, hence your type mismatch error.
If your type is an actual int, you just need to parse it:
AutoMapper.Mapper.CreateMap<Source, Destination>()
.ForMember(dest => dest.type, opt => opt.MapFrom(src => new OptionSetValue(int.parse(src.type))));
But if it's the actual text value for the option set, you'll need to lookup the text values using the OptionSetMetaData:
public OptionMetadataCollection GetOptionSetMetadata(IOrganizationService service, string entityLogicalName, string attributeName)
{
var attributeRequest = new RetrieveAttributeRequest
{
EntityLogicalName = entityLogicalName,
LogicalName = attributeName,
RetrieveAsIfPublished = true
};
var response = (RetrieveAttributeResponse)service.Execute(attributeRequest);
return ((EnumAttributeMetadata)response.AttributeMetadata).OptionSet.Options;
}
var data = GetOptionSetMetadata(service, "ENTITYNAME", "ATTRIBUTENAME");
AutoMapper.Mapper.CreateMap<Source, Destination>()
.ForMember(dest => dest.type, opt => opt.MapFrom(src => new OptionSetValue(optionList.First(o => o.Label.UserLocalizedLabel.Label == src.type))));
I have a table set up something like this:
Schema::create('capability', function($T) {
$T->string('code',32)->primary();
$T->string('name',64);
});
And a corresponding model like this:
class Capability extends BaseModel {
protected $table = 'capability';
protected $primaryKey = 'code';
public $timestamps = false;
}
When I seed some data like this...
$c1 = Capability::create(array(
'name' => 'Manage Clients',
'code' => 'manage_clients'
));
...and access the data members of $c1 like this...
echo $c1->name.", ".$c1->code;
...the result is Manage Clients, 0.
Why is the result not Manage Clients, manage_clients as I was expecting?
I needed to add public $incrementing = false to the model class.
Having one entity but two fieldsets, I found out that just one fieldset is populated when using the use_as_base_fieldset option.
Is there a solution for that problem?
First fieldset
class ProfileFieldset extends AbstractFieldset implements InputFilterProviderInterface
{
public function __construct($em)
{
....
$this->setHydrator(new Hydrator(false))
->setObject(new User());
...
}
...
}
Second Fieldset
<?php
use \Zend\InputFilter\InputFilterProviderInterface;
use Zend\Stdlib\Hydrator\ClassMethods as Hydrator;
use User\Entity\User;
class CredentialsFieldset extends AbstractFieldset
implements InputFilterProviderInterface
{
public function __construct($em)
{
.....
$this->setHydrator(new Hydrator(false))
->setObject(new User());
....
}
...
}
Form
use Zend\Stdlib\Hydrator\ClassMethods as Hydrator;
use User\Entity\User;
class UserForm extends AbstractForm
{
public function __construct()
{
....
$this->setHydrator(new Hydrator(false))
->setObject(new User());
....
$this->add(array(
'type' => 'User\Form\Fieldset\ProfileFieldset',
'options' => array(
'use_as_base_fieldset' => true
)
));
$this->add(array(
'type' => 'User\Form\Fieldset\CredentialsFieldset',
'options' => array(
'use_as_base_fieldset' => true
)
));
....
}
The entity itself contains properties for both fieldsets...
When binding the user entity for editing, just the last added fieldset is populated. Of course, there can be only one base fieldset ...
Anyone having an idea, how to solve that problem?
I think this could be done by creating a new fieldset that consists of the two fieldsets.
class UserForm extends AbstractForm
{
public function __construct()
{
$this->add(array(
'type' => 'User\Form\Fieldset\UserFieldset',
'options' => array(
'use_as_base_fieldset' => true
)
));
....
}
Then UserFieldset would become
<?php
namespace User\Form\Fieldset;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
use Zend\Stdlib\Hydrator\ClassMethods as ClassMethodsHydrator;
class UserFieldset extends Fieldset {
public function __construct()
{
parent::__construct('user');
....
$this->add(array(
'type' => 'User\Form\Fieldset\ProfileFieldset',
));
$this->add(array(
'type' => 'User\Form\Fieldset\CredentialsFieldset',
));
.....
}
public function init()
{
$this->setHydrator(new ClassMethodsHydrator(false))
->setObject(new User());
....
}
....
}
I have a CGridView and I want to search in it. The thing is that I have a column that is modified by a function in my model. Everything start in the search.php view that contains a cgridview that looks like this:
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'grid-demande',
'summaryText'=>'',
'dataProvider'=>$model->search(),
//'filter'=>$model,
'cssFile'=>Yii::app()->request->baseUrl."/css/my_gridview.css",
'columns'=>array
(
array(
'name'=>'id_post',
'htmlOptions'=>array('width'=>'16%'),
),
array(
'name'=>'fk_authorid',
'htmlOptions'=>array('width'=>'16%'),
'value'=>array($this,'renderNameDmd'),
),
)
As you can see the function renderNameDmd is called to render the name of the author. This function is in my model but is called from the controller:
protected function renderNameDmd($data,$row)
{
$model=$this->loadModelDmd($data->id_post);
return $model->getChAuthor();
}
And in the model class I call:
public function getChAuthor(){
$modelUsr=TUsers::model()->findByPk($this->fk_authorid);
return $this->fk_authorid.', '.$modelUsr->ch_completeName;
}
Everything works fine for displaying. My main problem is that I want to search through this cgridview and I can't search with the values that are displayed. Here is my search function that is contained in my model:
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
//more criterias
$criteria->compare('fk_cip',$this->fk_cip,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
For the moment, I have tried a couple of things but nothing worked so I reseted the code to what it was initialy. For now, if I search through my cgridview I can only filter with the authorid and not the full column format I wrote. Exemple:
For a row that looks like this:
3231, John Doe
I can only search through the:
3231
I want to search through the row I created from the function.
Thank you for your help!
Well, Yii is quite handy for this kind of feature, but you should first rewrite your model to use relations.
In your model :
// this attribute will be used in search function
private $_authorName;
public function rules()
{
return array (
.....
array('authorName', 'safe', 'on'=>'search'),
.....
);
}
public function relations()
{
return array(
.....
'author' => array(self::BELONGS_TO, 'TUsers', 'fk_authorid'),
.....
);
}
// authorName getter
public function getAuthorName()
{
if ($this->scenario=='search')
return $this->_authorName;
return $this->fk_authorid.', '.$this->author->ch_completeName;
}
// authorName setter
public function setAuthorName($authorName) {
$this->_authorName = $authorName;
}
public function search()
{
$criteria=new CDbCriteria;
.....
// search author name ?
if ($this->authorName!==null)
{
$criteria->with = array('author');
$criteria->compare('author.ch_completeName', $this->authorName, true);
}
.....
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
And in your CGridView, you should simply define your column like this :
array(
'name'=>'authorName',
'htmlOptions'=>array('width'=>'16%'),
),
And you should read this :
http://www.yiiframework.com/wiki/281/searching-and-sorting-by-related-model-in-cgridview/
I have a users, messages and comments.
users id user_id
messages id user_id
comments id message_id
I can get users data of the message using with().
$model = ORM::factory('message');
$messages = $model
->with('user')
->find_all();
with('comment') doesn't work. I guess because it's created for one-to-one relations while I have message has_many comment.
How do I get comments data into $messages? Like the following: ['message_id']['comment_id'][DATA]?
0. Define relationships:
User has_many Messages
Message has_many Comments
Message belongs_to User
Comment belongs_to Message
class Model_User extends ORM {
protected $_has_many = array('messages' => array());
}
class Model_Message extends ORM {
protected $_belongs_to = array('user' => array());
protected $_has_many = array('comments' => array());
}
class Model_Comment extends ORM {
protected $_belongs_to = array('message' => array());
}
1. Get user messages:
$messages = ORM::factory('user', $user_id)->messages->find_all();
foreach($messages as $message) {...}
2. Get message owner:
$user = ORM::factory('message', $message_id)->user; // without find_all()!
3. Get message comments:
$comments = ORM::factory('message', $message_id)->comments->find_all();
foreach($comments as $comment) {...}