Welcome Guest, Not a member yet? Register   Sign In
DMZ 1.7.1 (DataMapper OverZealous Edition)
#11

[eluser]Jack Scott[/eluser]
I just updated my app to DMZ 1.7.0 and ran into a fatal error. I'm not sure if this is a bug or not.

I added a block of code to my DMZ models to auto-load dependent models in the constructor, something like:

Code:
# make sure dependent classes are loaded
foreach (array('has_many', 'has_one') as $type)
    {
    foreach ($this->{$type} as $model => $properties)
        {
        $class = $properties['class'];
        if (! class_exists($class))
            {
            $this->CI->load->model($class);
            }
        }
    }

It broke with a
Quote:Fatal error: Uncaught exception 'Exception' with message 'Unable to call the method "_assign_libraries" on the class Rem4_property_file'
message when trying to load a dependent model in the constructor using the code above. I was able to work around the error by changing the _assign_libraries() function definition in datamapper.php. On line 6011, I changed

Code:
protected function _assign_libraries()

to

Code:
function _assign_libraries()

and the problem disappeared. Do you have any idea what happened here? Did I do something wrong?
#12

[eluser]OverZealous[/eluser]
@Jack Scott

Well, you are calling _assign_libraries in your own code somewhere, apparently the Rem4_property_file. Smile

That function is only accessed by DMZ internally. That's why it has been made protected. None of the methods that start with an underscore are publicly-accessible (and they never have been).

Search your code for that function. It shouldn't be used outside the DMZ source. You probably should just remove that method call altogether, where-ever you find it. There are actually quite a few methods that have been removed from public access.

This was documented in the upgrade instructions.

Edit:
I want to clarify the sentence above: I mean that none of the underscore methods have been documented and supported for use outside of the core library. In other words, they aren't part of the DMZ API, so they shouldn't be called directly.

Technically, they have been "public" before now, but that's because I only just recently decided to add visibility modifiers to the methods and properties.
#13

[eluser]rideearthtom[/eluser]
[quote author="OverZealous" date="1268775433"]@rideearthtom
It's not a bug in DMZ, I'm certain. You've most likely got something configured wrong.

First, it looks like a table prefix being added by CodeIgniter. You can't use CI's prefixes with DMZ - DMZ has it's own prefix management.

Second, the only reason DMZ looks for a join table is if it can't find an ITFK. It only looks for ITFK's on has_one joins (obviously), and the ITFK must be named {relationship_key}_id on the table for the model with the has_one.

The only ITFK I see in your models would be projectexposure_substyles.pe_style_id. If the field is not named exactly that, it won't work.

You might be getting tripped up because your classes have model names that don't match up with the table names.[/quote]

Thanks for the reply Phil.

There are no CI prefixes set up in my app, only the DMZ ones are configured, and in the above models they are overridden by 'projectexposure_' as shown in the code I posted. For this app the DMZ config'd prefixes are are 'tdb_' and 'tdb_join' (hence the generated SQL).

The way I understood your documentation was that it's possible to hardcode the table names into each model's class in order to fix discrepancies, but that this should work for any arbitrary table renaming.

Looking again at the error, it seems that DMZ is looking for a FK column name that matches the model name, not the table name. I.e., in the 'Pe_substyle' model, it's looking for 'pe_style_id' to make the join. But the 'Pe_style' model specifies that the table name is 'styles', not 'pe_styles'.

The manual reads as follows:

Quote:Joining tables must have a specially name id field for each of the tables it is joining, named as the singular of the table name, followed by an underscore (_) and the word id. For example, the joining id field name for table users would be user_id. The joining id field name for table countries would be country_id. This same column name could be used for in-table foreign keys

So unless I missed something fundamental regarding the overriding capabilities of var $table, it looks like there's a discrepancy between the documented behaviour and the actual behaviour. It's funny that I didn't notice this until this week as I've been working on this system with CI and DMZ for several months. Hope that I'm wrong and that the problem lies elsewhere.

Like I said, not too many real-life worries as I can always create the related object with a where clause on the FK column.

The fundamental problem is really this:

I have a database with several sets of prefixed tables, one for each of many applications. There's a central app which has it's own prefix and set of models, but it also needs to work with data from all other apps. I thought it would be as simple as creating more models and overriding the prefixes, but I ran into a problem when I realised that two apps would have different objects with the same name. No problem when designing the db as the prefixes would be different, but in the central app (which works with all the data) I'd end up with multiple models of the same name with different $prefix overrides, which is obviously impossible. So my workaround was to put another prefix on the model name for differentiation (pe_) and override the table name. Maybe there's a more elegant solution...?
#14

[eluser]Spir[/eluser]
Great! I'll upload my project with that new version and see if it works smoothly. Great job! Can't wait to test it.
#15

[eluser]OverZealous[/eluser]
[quote author="rideearthtom" date="1268822125"]
Looking again at the error, it seems that DMZ is looking for a FK column name that matches the model name, not the table name. I.e., in the 'Pe_substyle' model, it's looking for 'pe_style_id' to make the join. But the 'Pe_style' model specifies that the table name is 'styles', not 'pe_styles'.[/quote]

It is (slightly) incorrectly documented. (A lot of the documentation is a mix of old DataMapper and new DMZ, so some of it isn't perfect.)

DMZ uses the $table->model field when generating the ITFK name. The biggest reason for the difference in the docs is that $table is supposed to be the plural form of the model. The real purpose of the override is for table names with unusual pluralization.

This is the exact quote on tables from the manual:
Quote:Normal tables must be named the lowercase, pluralised version of the object name. So for a user object of User, the table would be named users. For Country, it would be countries. (For odd pluralizations, you may need to hard code the $table or $model fields.)

So, it's not intended that you would have arbitrary table names. However, it should work in your case, just rename the ITFK column correctly.

It's not really a bug, just that you are using the application a bit outside it's intended design.
#16

[eluser]Mareshal[/eluser]
Still getting this:


Code:
Parse error: syntax error, unexpected $end in D:\xampplite\htdocs\em\system\application\controllers\admin.php on line 198

Line 198 contains only }

Usually this is because of an unclosed tag, but now...
#17

[eluser]OverZealous[/eluser]
[quote author="Mareshal" date="1268877520"]
Code:
Parse error: syntax error, unexpected $end in D:\xampplite\htdocs\em\system\application\controllers\admin.php on line 198
[/quote]

That means the error is in your code. If the error was related to DMZ, it would mention one of the DMZ files.

A parse error basically means a typo.

Run this on the command line to see that it is your file:
Code:
php -l D:\xampplite\htdocs\em\system\application\controllers\admin.php

(This assumes PHP is a global executable.)
#18

[eluser]Mareshal[/eluser]
Actually is your example from rar Wink
#19

[eluser]TheJim[/eluser]
@Jack Scott, OverZealous

Quote:It broke with a
Fatal error: Uncaught exception 'Exception' with message 'Unable to call the method "_assign_libraries" on the class Rem4_property_file'

To offer an alternative to what Phil said, I believe the problem is that you're loading the class via CI's Loader, which calls _assign_libraries. If you follow the DMZ way of not calling load->model and just do a "new Whatever()" you shouldn't run into that problem.

On a side note, I don't see why you'd really need to auto-load related models in your model's constructor, because accessing the related variable, e.g. "$user->group" will auto-load the related class anyway. That's just part of DMZ. And if you wanted the model in your controller, instantiating a DMZ model (as in the above paragraph) auto-loads as well. So maybe you have some reason for doing so, but I'd guess that you're going about it the hard way and that extension to the constructor isn't necessary.

Letting the built-in lazy loading of related classes do its thing rather than loading all related classes whenever one is instantiated is bound to have some performance benefit too, possibly significant if you've got a bunch of classes all related to each other.
#20

[eluser]OverZealous[/eluser]
[quote author="Mareshal" date="1268878369"]Actually is your example from rar Wink[/quote]

By example, you mean the example app, or examples in the docs?

I just tried the example application, completely resetting it, and never saw the error. There might be a typo in the docs, however.




Theme © iAndrew 2016 - Forum software by © MyBB