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

[eluser]coldscooter[/eluser]
Hi, is there a why to quickly check if there are any changes to the stored values while making a save on a model object?

I basically want to intercept the save() method in the model and do a check to see if there are any changes.

Thanks in advance.

[eluser]WanWizard[/eluser]
No. But Datamapper does this check internally, and won't run an UPDATE query if nothing has changed.

It does that by doing:
Code:
// Convert this object to array
$data = $this->_to_array();

// Prepare data to send only changed fields
foreach ($data as $field => $value)
{
// Unset field from data if it hasn't been changed
if ($this->{$field} === $this->stored->{$field})
{
  unset($data[$field]);
}
}

// Only go ahead with save if there is still data
if ( ! empty($data))
{
// Update existing record
$this->db->where('id', $this->id);
$this->db->update($this->table, $data);
}

[eluser]arif_stalker_majid[/eluser]
To Doctor WanWizard,

Its a very nooby question to ask but kindly tell me why should i migrate to datamapper rather than using the built in CI active record ?
Cuz i found the development time in DM to be far more than the CI's AC(which is a query builder actually).

thank you and waiting for your reply..............

[eluser]WanWizard[/eluser]
Short answer: if that is the case then you're doing something wrong. Wink

Most common mistake: use Datamapper as a glorified query builder. I see this happen with (probably) most people that use an ORM, maybe not supprising as most documentation hints at using it that way.

What I mean with that is that you have code like this in your controller:
Code:
$u = new User();
$u->where_related('project/task/status', 'label', 'completed')->get();
which basically isn't much different then using a normal QB, albeit probably less complex as the ORM will abstract the complex joins behind it.

Instead, you should still use the Model as intended in the MVC architecture, which is to abstract your data interaction away from your controller. So given the exampla above, your model should contain a method like
Code:
public function get_by_project_status($status = 'completed')
{
    // reset the current object
    $this->clear();

    // run the query
    $this->where_related('project/task/status', 'label', $status)->get();

    // return the object for chaining
    return $this;
}
and then in your controller use
Code:
$u = new User();
$u->get_by_project_status('open');

Note that this is just an example, you'd probably will make the methods a bit more generic, and you might include some post-processing as a well (for example array conversions for dropdowns)...

[eluser]cahva[/eluser]
Hi,

I have a REALLY annoying problem with identifiers. This might not be DM related but maybe someone can shed some light because I'm frustrated as hell.

I have multiple sites, they are CI 1.7.2 and use the same symlinked system and application(for most parts) directories so no conflicts with different versions.

When running this on 2 different sites(both with same DM(1.8.0) and CI). It has lots of other stuff going on before this(subqueries etc.) but this is the relevant one:
Code:
echo $products->order_by_func('IF', '@special_price IS NOT NULL, special_price, price', $pr_data['order_dir'])->where('active',1)->get_sql();

Working site gives this:
Code:
SELECT products.*, products_description.name AS products_description_name, products_description.description AS products_description_description, products_description.key AS products_description_key, products_description.language_id AS products_description_language_id, tax.amount AS tax_amount, (SELECT product_specials.price
FROM (product_specials)
WHERE `product_specials`.`customer_group_id` = '1'
AND product_specials.product_id =products.id
AND  (
  (
`product_specials`.`date_start` = '0000-00-00'
OR `product_specials`.`date_start` <= '2012-07-17'
)
AND  (
`product_specials`.`date_end` = '0000-00-00'
OR `product_specials`.`date_end` >= '2012-07-17'
)
)
LIMIT 1) AS special_price
FROM (products)
LEFT OUTER JOIN products_description products_description ON products.id = products_description.product_id
LEFT OUTER JOIN tax tax ON tax.id = products.tax_id
WHERE `products_description`.`language_id` = 1
AND `products`.`active` = 1
ORDER BY IF(special_price IS NOT NULL, special_price, products.price) asc

Non-working site gives this:
Code:
SELECT `products`.*, `products_description`.`name` AS products_description_name, `products_description`.`description` AS products_description_description, `products_description`.`key` AS products_description_key, `products_description`.`language_id` AS products_description_language_id, `tax`.`amount` AS tax_amount, (SELECT `product_specials`.`price`
FROM (`product_specials`)
WHERE `product_specials`.`customer_group_id` = '1'
AND product_specials.product_id =products.id
AND  (
  (
`product_specials`.`date_start` = '0000-00-00'
OR `product_specials`.`date_start` <= '2012-07-17'
)
AND  (
`product_specials`.`date_end` = '0000-00-00'
OR `product_specials`.`date_end` >= '2012-07-17'
)
)
LIMIT 1) AS special_price
FROM (`products`)
LEFT OUTER JOIN `products_description` products_description ON `products`.`id` = `products_description`.`product_id`
LEFT OUTER JOIN `tax` tax ON `tax`.`id` = `products`.`tax_id`
WHERE `products_description`.`language_id` = 1
AND `products`.`active` = 1
ORDER BY IF(`special_price` IS NOT NULL, `special_price`, `products`.`price)` asc

The actual error will come from the last ORDER BY line with `products`.`price)`. But the non-working query also has identifiers all over the place and this is puzzling me. Database, datamapper and other configs are identical so what possibly could cause this kind of behaviour?

I've made the fix stated here also but it has no effect to the identifiers at all and working site works without the fix no problem.

[eluser]WanWizard[/eluser]
Datamapper's order_by() is an alias for $this->db->order_by(), all escaping happens in the CI database layer.

So either both applications use a different system folder (using different database code) or you're using two different database drivers (and there is a difference in escaping between both). I can't think of any other reason why this could happen.

[eluser]cahva[/eluser]
I found the problem! Files were exactly the same so it was not that.

In the other site I used "bestsellers"-addon, which had this in the model(non-datamapper):
Code:
$this->db->select("COUNT(product_id) pr_count,product_id",false)->order_by('pr_count','DESC')->limit($limit)->group_by('product_id');

The earlier query worked for the other site as this little line has the "false" set as second parameter in the select method and from this query on, the rest of the queries are affected and are without(or are MOSTLY without) identifiers.

Maybe time to upgrade CI(and DM) for our eCommerce maybe? Smile

[eluser]coldscooter[/eluser]
I'm having trouble using include_related().

If i'm doing something like:

$user->include_related('address');

I get results only for users that have a address record. But i would like to see all users even if they have no address record, and just show null values if the address is missing.

Could someone help?

[eluser]WanWizard[/eluser]
It does a 'LEFT OUTER' join, and that can't be changed (it's hardcoded).

Reason for it is that you're asking for users with a related address.

[eluser]coldscooter[/eluser]
I having an issue when running a GET() after having run a SAVE().

After the save we then want to use the same object to run an additional query, with a new where array.

What i'm finding is, after the save, there are lots of additional 'where's added to the object so that once i reuse the object for a new GET, I end up with malformed sql statement.

Is this a bug? Am i able to reuse the object without creating a new one?

[edit:]
I'm running a where_related before the SAVE(). Example:
Code:
$this->users->where_related('comment', 'id', $this->current_user->id);
$this->users->save($some_object);

$this->users->include_related('blog_posts')
$this->users->where(array('id'=>1));
$this->users->get();

[edit:]
Sorry, i've realised that this issue was being caused by having incorrect relationships set up in the model. Apologies for the hasty post.




Theme © iAndrew 2016 - Forum software by © MyBB