Welcome Guest, Not a member yet? Register   Sign In
DataMapper ORM v1.8.2

[eluser]rick20[/eluser]
It's weird, because I'm quite sure I already replace my datamapper library, but the problem still appears.
The latest version is 1.8.3-dev right?
Do you have any advice how to identify the problem in my case?

[eluser]WanWizard[/eluser]
I've did some debugging, the only race condition I can find is that if when you save validation fails, before it processes the field it needs to serialize, the field will be left in array state.

[eluser]rick20[/eluser]
oh man...sorry for my mistake Sad
I just found that the problem is caused by initial preferences I put in __construct() in my model, just after parent::__construct($id).
After I moved parent::__construct($id) as the last line, it works great Smile
So thankful to have datamapper!
Thanks alot once more Smile

[eluser]rick20[/eluser]
looks like I have another problem.
Just wondering, what is the best way to set default value of a field in a model?
After some googling, I can only find this post about setting default value
http://ellislab.com/forums/viewthread/14...90/#958909

Quote:... If you need default values for new objects, add a method to your model that sets them when not exists(), and call that method before you load the view. Alternatively, you can call it from __construct() (and probably clear() as well) to do it automatically.

I would like to put the default values in my constructor.
And then, I write my model like this:

Code:
class User extends DataMapper {
  public $validation = array(
    'preferences' => array(
        'rules' => array('serialize'),
        'get_rules' => array('unserialize')
    )
  );

  function __construct($id = NULL)
  {
    parent::__construct($id);
    
    $CI = &get;_instance();
    
    if (!$this->exists())
    {
      $prefs = array('show_email' => TRUE, 'show_name' => FALSE);
      $this->preferences = $prefs;
    }
  }
}

And then in my controller:

Code:
public function index()
{
  $user = new User(32);
  print_r($user->preferences);
  $user->username = 'aaa';
  //$user->preferences = array('aaaa', 'bbbb');
  print_r($user->preferences); print 'c';
  $user->save();
  print_r($user->preferences); die('d');
}

With these lines, I found that if I set $user->preferences, the save() will be succeed.
But, if the line is commented, save() will failed, with same error as previous error.

Btw, I put back the parent::__construct($id); to the first line in constructor because it will clear all properties I think.

So, I just wonder, what is the best way to set default values on my model?
Thank you

Edit:
After further test, it seems that the error raised when I set $user->preferences with the same value (I think datamapper thinks that the property is not changed, so it won't execute serialize() and when _run_get_rules() being executed again, it will try to unserialize an array).

[eluser]WanWizard[/eluser]
I'll add an is_array() check to unserialize when I have the time to avoid any errors.

[eluser]rick20[/eluser]
That would be great!
Meanwhile I just override the _serialize and _unserialize in my model as follow:

Code:
protected function _serialize($field) {
    // if (is_array($this->{$field})) I just notice this line already check is_array :(
      $this->{$field} = is_array($this->{$field}) ? serialize($this->{$field}) : array($this->{$field});
}

protected function _unserialize($field) {
    if (!is_array($this->{$field}))
      $this->{$field} = empty($this->{$field}) ? array() : unserialize($this->{$field});
}

Until now it solves the problem, hopefully no side effects after this Big Grin
Thanks a lot!

[eluser]Maglok[/eluser]
Can datamapper do this for me?

Class Organisation has many Class CCClass
Class CCClass has many Class Feature

I want the features that CCClass has to be limited to the features denoted by the count column in class Level.

Example: Level 4 has a CCClass of 'Employee'. I then want the Features of Employee with Organisation count 4.

I could just create a relationship between CCClass and Feature, but that would ignore the fact that I want to limit the set of features of a CCClass based on the count of the parent Organisation.

I can do this by writing a get function that does it, but I much rather create a relationship. I don't see a particular way to do this (or if datamapper should be able to do this in the first place).

[eluser]matyhaty[/eluser]
Hi All

Struggling to do a many/many relationship pull....
Ill try and explain this as best as possible.......

A task has one or more departments who are dealing with the Task
A user has one or more departments.

Thus, I would like to get all tasks for 'a user' which are related to any of that users' department(s)
This is easy if the user has one department, but cant seem to work it out if they have more than one.....

The code which would sorta do it is this:

Code:
$t = new Task();
$res = $t->where_related_department('code', 'OPS')->where_related_department('code', 'PRO')->get();

(which doesnt work)

Running either of these seperatly work fine....
Code:
$t = new Task();
$res = $t->where_related_department('code', 'OPS')->get();
or
$t = new Task();
$res = $t->where_related_department('code', 'PRO')->get();

As the system get more complex with more filters it would be good to further that still...
E.g. Show all tasks which are related to departments, depots (and other models) which are related to 'a user'

Is this possible?

Thanks in advance.


[eluser]rick20[/eluser]
Got another issue...
I have 2 models that have 2 many-to-many relationships :

Code:
class User extends DataMapper {

  var $has_many = array(
    'favorited_item' => array(
      'class'         => 'item',
      'other_field'   => 'favorited_user',
      'join_table'    => 'favorites',
      'join_self_as'  => 'user',
      'join_other_as' => 'item'
    ),
    'ordered_item' => array(
      'class'         => 'item',
      'other_field'   => 'ordered_user',
      'join_table'    => 'orders',
      'join_self_as'  => 'user',
      'join_other_as' => 'item'
    )
  );
}

class Item extends DataMapper{

  var $has_many = array(
    'favorited_user'  => array(
      'class'         => 'user',
      'other_field'   => 'favorited_item',
      'join_table'    => 'favorites',
     'join_self_as'  => 'item',
      'join_other_as' => 'user'
    ),
    'ordered_user' => array(
      'class'         => 'user',
      'other_field'   => 'ordered_item',
      'join_table'    => 'orders',
      'join_self_as'  => 'item',
      'join_other_as' => 'user'
    )
  );
}

Table 'orders' has a field 'status'.
Now, I want to get all ordered item with status 'active' from a given user.
I try this but doesn't work:

Code:
$user = new User(1);
$user->ordered_item->where_join_field('ordered_user', 'status', 'active')->get();

Quote:Unknown column 'mc_orders.status' in 'where clause'

SELECT `mc_item`.* FROM (`mc_item`) LEFT OUTER JOIN `mc_orders` ordered_user_orders ON `mc_item`.`id` = `ordered_user_orders`.`item_id` WHERE ( `mc_orders`.`status` = 'active' ) AND `ordered_user_orders`.`user_id` = 1

what am I doing wrong here?

[eluser]rick20[/eluser]
Hi @matyhaty, maybe you can change

Code:
$t = new Task();
$res = $t->where_related_department('code', 'OPS')->where_related_department('code', 'PRO')->get();

to

Code:
$t = new Task();
$res = $t->where_related_department('code', 'OPS')->or_where_related_department('code', 'PRO')->get();

As for the complex relations, what I can think of is something like this:
First, find out all departments, depots, and other models that 'a user' has a relation with, and then loop through all of them to build the criteria for the task model object.
Maybe like:

Code:
foreach ($user->departements as $departement)
  $task->or_where_related_departement('code', $departement->code);

foreach ($user->depots as $depot)
  $task->or_where_related_depot('code', $depot->code);

//..and so on..

$task->get();

Hope this helps




Theme © iAndrew 2016 - Forum software by © MyBB