IntroductionIt's simple, you declare your model with all validation rules that come with it. Nothing new here, but now you declare a form which retrieves the model and you select which fields the form should have. You can now ask the form to display with all the values from the model. Example of declaring a form. class User_Form_Core extends Model_Formation{
//Exclude these fields, all other fields in the model are displayed
protected $exclude=array('id','modified','created','role_id');
//Include these fields, all fields not in here are not displayed
protected $form_fields=array();
//Which model this form takes after
protected $_model='User_Model';
protected $disabled=array('modified'); //shows the form field but disabled so it can't be edited.
}Example of the model class User_Model extends ORM{
protected $validate=array(
'name'=>array(
'rules'=>array(array('Rule_Max_Length',50)),
'pre_filters'=>array('ucfirst')
),
'email'=>array(
'type'=>'email',
'rules'=>array('Rule_Required'),
),
'preference'=>array(
'type'=>'checklist',
),
'comment'=> array(
'pre_filters'=>array('trim'))
);
}Now you can start generating your forms: A random controller public function create_user()
{
$form=new User_Form();
if($form->save())
{
echo 'User saved';
}
else
{
echo $form->render();
}
}
public function edit_user($id)
{
$form=new User_Form($id);//or $form=new User_Form(new User_Model($id));
if($form->save())
{
echo 'User saved';
}
else
{
echo $form->render();
}
}That's it, the render() method will give you a form with rules, validation and all retrieved from the model. Easy for your backend and perhaps your frontend if you need some forms quickly. Remember, the form is an instance of Formation so you can do this:
public function edit_user($id)
{
$form=new User_Form($id);
$form->add_element('password','password_match')->add_rule('Rule_Matches',$form['password']);
if($form->save())
{
echo 'User saved';
}
else
{
echo $form->render();
}
}You can change the entire form after you retrieved it from the model. But you can also change stuff from your User_Form class, such as the template class User_Form_Core extends Model_Formation{
//...
protected $template='your_template';
}
|
Should the model not extend ORM ?
I'm having some trouble getting this to work.
I have a Page controller:
public function fresh(){ $form=new Page_Form(new Page_Model()); if($form->save()) { $this->template->main= 'Page saved'; } else { $this->template->main= $form->render(); } }and a Page_Form?:
class Page_Form_Core extends Model_Formation{ protected $exclude = array(); protected $form_fields=array('title','menu', 'id', 'order'); protected $_model='Page_Model'; }And a model:
class Page_Model extends ORM { protected $validate=array(); //protected $custom_field_data=array('title'=>'title');And this is my table
But the build_form() method does not find anything
protected function build_form($guess_fields=true) { //pr($this->_model->field_data()); foreach($this->_model->field_data() as $name=>$property) { if(in_array($name,$this->exclude)) continue; if($this->form_fields!=array() and !in_array($name,$this->form_fields)) continue; ......It looks like the function $this->model->field_data() is meant to get the fields in the table but the array is always empty.
$this->model looks like this
Page_Model Object ( [has_many:protected] => Array ( [0] => columns ) [validate:protected] => Array ( ) [auto_save:protected] => [class:protected] => page [table:protected] => pages [select:protected] => [where:protected] => [object:protected] => stdClass Object ( [id] => [title] => [menu] => [order] => ) [changed:protected] => Array ( ) [has_one:protected] => Array ( ) [belongs_to:protected] => Array ( ) [belongs_to_many:protected] => Array ( ) [has_and_belongs_to_many:protected] => Array ( ) )Any suggestions ?
I think I understand something.. field_data() is a method of The Database object. You can say $db = new Database(); $db->field_data($tablename); and It will return an array containing each field in the table as the array key and an array of field metadata as the value. Different databases will return different sets of information about the fields.
But I don't think ORM models have this method. In fact i think they explicitly deny this
ORM.php line 430:
// Do not allow query methods if (preg_match('/query|get|list_fields|field_data/', $method)) return $this;Ok , here is what I did to make it work for me:
protected function build_form($guess_fields=true) { // Martin hack..first find table name from $_model $table= str_replace('_Model','',get_class($this->_model)); $table = inflector::plural(strtolower($table)); // get field data $db = new Database(); $fieldData = $db->field_data($table); // transform to array foreach($fieldData as $d){ $field = get_object_vars($d); // lowercase keys foreach($field as $name=>$value){ $field_two[strtolower($name)]=$value; } // build fields array $fields[$field_two['field']]= $field_two; } // end Martin hack foreach($fields as $name=>$property) { if(in_array($name,$this->exclude)) continue; ....Can't help thinking we must be doing things in a different way since you get the field data by doing : $this->model->field_data() and I have to make the above hack... ???
I corrected the User_Model? extends ORM, thx
You're right in saying I did it a little different. ORM always retrieves database field data and puts it in a static property, using a new method I retrieve this information and utilize it for looping over the fields and add the length rules.
This library is great. Thank you. Onr small problem. Can't seem to set a required validation rule if field type is set to dropdown, or checklist. Always fails validation
Hmm.. another problem. Formation screws up my ORM many-to-many table in another controller. Insists on writing SQL using roles_users rather than users_roles. fine once I remove the module.
Classis case of bug vs. feature. There is a method in MY_ORM file named find_related or something. This is actually a patch that will enable from User_Model? find_related_roles as well as Role_Model?->find_related_user. The order of the pivot table has to be alphabetic though(so roles_users like in RoR) Kohana only supports find_related_x one-way only.Remove the find_related method and it's fixed.
hi,is there a version working in kohana 2.2?
Hello, I have a problem, how to update record? Even if I add ID field the Formation is trying to create a new record (it uses INSERT INTO not UPDATE sql statement. How to solve it?