Welcome Guest, Not a member yet? Register   Sign In
[Deprecated] DMZ 1.5.3 (DataMapper OverZealous Edition)

[eluser]OverZealous[/eluser]
That is really weird, since this:
Code:
$object->get(1);
Call this:
Code:
$this->db->get($this->table, $limit, $start);
Which is simply this inside Active Record:
Code:
// ...
if ( ! is_null($limit))
{
    $this->limit($limit, $offset);
}
// ...

And $object->limit(1) just calls $this->db->limit directly.

Just to make sure I wasn't crazy, I tried using ->limit() in the test code, under both MySql and Postgres. It definitely works here, so there is something going on with your setup. Sad What DB driver are you using?

If you wanted to do a little more research, see if this code renders a value:
Code:
$state->import-limit(1);
$lim = $state->import->db->ar_limit;
echo("[$lim]"); // should print [1] to the browser
$state->import->get();
$state->import->check_last_query(); // renders out the last query

Of course, as mcnux mentioned, almost everyone just calls get($limit, $start).

[eluser]leviathan28[/eluser]
I'm using the latest mysql_driver from the codeigniter svn.

Code:
$state = new State();
$state->get_by_id(State::STATE_NEW);
$state->import->limit(1);
$lim = $state->import->db->ar_limit;
echo("[$lim]"); // should print [1] to the browser
$state->import->get();
$state->import->check_last_query(); // renders out the last query

results in

Code:
[1]

SELECT `imports`.*
FROM (`imports`)
LEFT OUTER JOIN `imports_states` as imports_states ON
    `imports`.`id` = `imports_states`.`import_id`
LEFT OUTER JOIN `states` as states ON `states`.`id` =
    `imports_states`.`state_id`
WHERE `states`.`id` = '1'

So - still no limit in the query.

When I remove line 743 in datamapper.php $this->limit($limit, $offset);, it works. Could it be that the limit I set is replaced by the default values of the get() function?

[eluser]OverZealous[/eluser]
Not unless you've overridden them. The default values of get() match the default values from ActiveRecord. And, of course, it "works for me" ;-)

Did you customize your get function in your model or an extension class?*

* By extension class, I mean Extending DataMapper Directly, not a DMZ extension.

[eluser]leviathan28[/eluser]
No, it's quite a new project and the models are all empty except for the constants I use in the State-Model. And I didn't extend DataMapper.
In fact, there's hardly anything I changed on the whole project, it's all pretty much standard. If the error lies within my setup, I have no clue where to look for it.

Btw: Is there a reason why count() returns a string instead of an integer?

[eluser]OverZealous[/eluser]
Well, I'm sorry I can't figure it out! I don't know what else to try. I'll keep thinking about it.

If you are getting strings instead of ints, it's the DB driver or PHP. I have that problem with Postgres for ids (and it can throw errors when saving them back later). I haven't taken the time to see if the bug is possibly in CodeIgniter (or the PHP v5.2.10 I'm using), but it is annoying. What little research I've done makes me think it is just PHP. 8-(

[eluser]OverZealous[/eluser]
@leviathan28
Oh, hey, I just duplicated the bug! I'm looking into why it's happening. You may be right about it being related to limit being overridden by get...

UPDATE:

Bug found! Such a silly thing I missed it earlier. It only occurs (occurred) when you use this form:
Code:
$parent->child->limit(N)->get();

If you didn't have a parent, or set the limit on get(), everything was peachy keen.

Anywho, the bug's been fixed, and you get your name on the credits page ;-)

[eluser]macigniter[/eluser]
i am currently setting up a database for a new application and was wondering if something like this is possible with datamapper?

i have three tables: users, groups and offices

every user can belong to multiple offices and also belongs to 1 group per office

so my current approach is to add a joining table that has three primary keys:
group_id
office_id
user_id

since the relationship between the user and office as well as the group needs to be saved. how would something like this be set-up in datamapper? i guess i could work with a join field in the user-office relationship. but that doesn't create an actual relationship between user-group that can be accessed via the datamapper methods!? i am puzzled...

[eluser]OverZealous[/eluser]
@macigniter
The usual way to do this is to have a dedicated class to track the relationships.

I have a small example here, but the basic process is that you would create a class that was called, for example, UserOfficeGroup.

This class would have a $has_one relationship with User, Office, and Group. User, Office, and Group would otherwise be unrelated. Each of the other objects would have a $has_many relationship back to UserOfficeGroup. The table for UserOfficeGroup only contains four columns:
• id
• user_id
• office_id
• group_id

You would run queries like this:
Code:
$user = ...
$offices = new UserOfficeGroup();
$offices->where_related($user);
$offices->include_related('office', '*', FALSE); // the FALSE gets all office fields without a prefix
$offices->include_related('group', '*'); // replace * with an array of fields, if you prefer
$offices->get();
foreach($offices as $office) {
    // NOTE: The office ID must be gotten as $office->office_id
    $office_name = $office->name;
    $group_name = $office->group_name;
}

Which I would probably pack into a method off of the User class, if you use it a lot. You can also swap around User, Office, and Group depending on what the query starts with.

The drawback to this method is that it is more difficult to edit and update the objects from a related point of view. For example, you can't modify and then save the "Office" in the example, because it is really a UserOfficeGroup object. Also you have to remember to manually delete any related UserOfficeGroup objects when deleting a User, and Office, OR a Group.



An alternative method is to add a column to the offices_users relationship join table. I'd call it group_id. Then you can easily look up $office->users and $users->office. If you need the group, it looks like this:
Code:
$user->offices->include_join_fields()->get();
foreach($user->offices as $office) {
    $group = new Group();
    $group->get_by_id($office->join_group_id);  // if there are a lot of offices, this can generate a lot of queries!
}

The drawback to this method is it hard to enforce within the database (no validation rules, for example), and cannot be retrieved with one query (like above).

[eluser]macigniter[/eluser]
thanks, phil!! you're so quick and detailed, just amazing.

i think that option #2 would be much easier and appropriate for the usage. since i will be looking up the group_id only once for authentication and then most probably store this value in the session it would be much easier to do it this way. there's not even a need to loop through it since i only need to look up the value for one specific combination of user and office.

whenever the group_id will be changed for a specific user/office combination it will be easy to do with the second approach.

thanks again!!

[eluser]leviathan28[/eluser]
Quote:If you didn’t have a parent, or set the limit on get(), everything was peachy keen.

Anywho, the bug’s been fixed, and you get your name on the credits page wink

Great Smile

about the strings: Seems to me like the active record class is responsible - at least everywhere else, integers are used but in DB_active_rec.php the count_all_results() even returns a quoted 0
Code:
if ($query->num_rows() == 0)
{
return '0';
}


I don't know if that would make sense, but couldn't you just replace in datamapper.php?
Code:
return $this->db->count_all_results();
with
[code]
return (int) $this->db->count_all_results();
[/quote]




Theme © iAndrew 2016 - Forum software by © MyBB