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

[eluser]Mareshal[/eluser]
I have a table, that is in a relation: one to many with other 4 tables.

But the following code executes 5 queries. Why not use JOINs ?
Code:
$v = new Video(1);
    $v->video_category;
    $v->video_rating;
    $v->video_flag;
    $v->video_stat;

LE:

I've reduced it to this
Code:
$v->include_related('video_category')
      ->include_related('video_rating')
      ->include_related('video_flag')
      ->include_related('video_stat')
      ->get_by_id(1);

But when I am accessing the video_category object, it makes another query
Code:
foreach($v->video_category as $a) echo $a->category_id . "; ";

[eluser]WanWizard[/eluser]
In your first example you have 5 different statements in which you request data the current object doesn't have. How would you implement that using JOIN's? Make the code physic so it knows at the first statement that you intent to write more?

The second example shows you Datamapper will use JOIN's when it has the entire question in a single statement.

Your third statement is a repeat of the first. There you say "Oh, and I need this too". How would Datamapper know in the previous statement that you intend to ask for more data later?

[eluser]North2Alaska[/eluser]
@WanWizard

I would like to add some features to DataMapper. I'm not sure how to go about it or how/where best to do it. Here is what I want to add.

1) When the columns exist, store the create/update fields in the joining table.
2) Config option to store the update field at the same time as the create field.
3) Config option to store a create/update user id when the columns exist.

1) I'm not sure where to even begin on this one. The idea is that I want/need to capture when the relationship was established. For example user and group. I want to know when the user was added to the group. This becomes even more important when the joining table has additional data.

2) I think I could create a new value in the config file:
Code:
$config['update_on_create'] = FALSE;
and then in the save function add the code to do the work.

3) The idea here is that I would like to know who created/updated the record and I would like to have it automatic if the field exists. I've played around with this and have not been successful. The config could/should define the variable to be used for this value, the created_user_field, and updated_user_field. I can use the same method to check for the existence of the fields, I can't figure out the best way to populate the value to store.

I would be glad to do the work, I just need some direction on how/where and if you feel these would be valuable additions.

Your thoughts?

[eluser]WanWizard[/eluser]
To start with a general remark: this is not really generic functionality that should belong in Datamapper. It's specific to your case. Best way to implemented is to create a base model that extends Datamapper, add your specific functionality to it, and have all your models extend this base model instead of Datamapper.

2) and 3) can be solved by overloading the save() method, 1) can be achieved by overloading the _save_relation() method.

This way you don't have to patch the Datamapper library, which will lead to headaches when it's time to do a version upgrade.

[eluser]North2Alaska[/eluser]
[quote author="WanWizard" date="1332428716"]To start with a general remark: this is not really generic functionality that should belong in Datamapper. [/quote]

That was really the heart of the question. OK, I'll work on your suggestions. I've already overloaded the Save function and can look into the other.

Thanks.

[eluser]animatora[/eluser]
I am new to DataMapper ORM in CodeIgniter, here is my question. According to the manual :

Code:
Be careful with this method. Without having limited it with where statements or similar methods it will modify every single row on the table!

Also, this method bypasses validation, and can also operate on in-table foreign keys, so please be aware of the risks.

If the update method bypasses validation, what is the way to update a record validating it before update? A sample code will be appreciated.

[eluser]North2Alaska[/eluser]
[quote author="animatora" date="1332444356"]I am new to DataMapper ORM in CodeIgniter, here is my question. According to the manual :

Code:
Be careful with this method. Without having limited it with where statements or similar methods it will modify every single row on the table!

Also, this method bypasses validation, and can also operate on in-table foreign keys, so please be aware of the risks.

If the update method bypasses validation, what is the way to update a record validating it before update? A sample code will be appreciated.[/quote]

I think the best way is to use the Save function.
Code:
$u = new User();
$u->get_where("id", 1);

$u->first_name = "Bill"
$u->last_name = "Jones"

$u->Save();

[eluser]WanWizard[/eluser]
Correct.

You don't use the update() method to update your record, it's meant for mass updates to your table (it generates an UPDATE query).

The save() method will determine automatically if an INSERT or UPDATE is needed to save the current object state.

[eluser]North2Alaska[/eluser]
[quote author="North2Alaska" date="1332432074"]
I've already overloaded the Save function and can look into the other.
[/quote]

Well, I don't see how to overload a Protected function. Two problems arrise. 1) The _save_relation uses other protected functions that are not reachable from the overloading Class. 2) I can't call parent::_save_relation to have it do normal operations like I did with the Save function.

I think this functionality has to be internal to DM. Not sure what else to do. (Showing my Noobness :-D )

[eluser]rherriman[/eluser]
I'm having an issue I hope that you can provide some insight on, WanWizard. For reference, we are currently using DM 1.8.1 on CI 2.0.2--they've been a little reluctant to upgrade here at work after those issues introduced in 2.0.3 with protected methods. But I don't think this is related to my problem.

In several of my models now, I've taken to extending the __get magic method in certain cases: when simple $object->relation querying doesn't suffice. For example, we have "categories" (infinitely deep) and "products" that are assigned to them. We also have "media" that we can attach to either categories or products. Now let's say that I want to get a (distinct) list of media for a particular product, as well as the media assigned to its direct parent category. $product->media->get() won't provide that. Ideally, too, that functionality would be part of the model itself. My solution was to do this:

Code:
class Product extends DataMapper {
...
public function __get($name) {
  // Prepare the resolved_media property. More than just an alias of
  // media, this will also retrieve the UNION of $product->media and
  // $product->category->media.
  if($name == 'resolved_media') {
   $this->{$name} = new Media();
  
   if(!$this->exists()) {
    // Ensure an empty result set is returned if this product does
    // not exist yet: if it doesn't exist, there are no relations.
    // Yes, I know this is kind of... unpleasant.
    $this->{$name}->where('id', 0);
   } else {
    $this->{$name}->distinct();
    $this->{$name}->group_start();
    $this->{$name}->where_related_product('id', $this->id);
    $this->{$name}->or_where_related('category/product', 'id', $this->id);
    $this->{$name}->group_end();
   }
  
   return $this->{$name};
  }

  return parent::__get($name);
}
...
}

This works as I had hoped. You can do $product->resolved_media->{other query methods}->get() and end up with the results you would expect. However, it only seems to work correctly once. If you want to run another query on resolved_media, it ignores all of the filtering defined in __get. It does, however, honor method chaining. resolved_media itself just becomes something of a blank slate, no different than if you were running queries on a fresh instance of Media.

This is one of the simpler examples that I have. Ultimately I'm providing these as short hand for the other developers on my team who are less well versed in writing DataMapper queries. Plus, it has a nice side benefit of helping to promote consistency in query results across the application.

I'm sure that I'm missing something completely obvious. Are you able to see what I'm doing wrong?

- ryan

EDIT:
Naturally, no more than 20 seconds after posting this I realized what was going on. After the query is run and the results retrieved, the actual "query" itself is wiped clean just like it would be for any DM object. So I guess, a different question: once get() is called on resolved_media, is there a way for me to restore this "default" query?




Theme © iAndrew 2016 - Forum software by © MyBB