ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

[Deprecated] DMZ 1.6.2 (DataMapper OverZealous Edition)

November 23, 2009 11:54pm

Subscribe [46]
  • #316 / Feb 19, 2010 12:20pm

    NachoF

    171 posts

    Say you have Users with email field with a rule validation that its unique…. how come when I want to update some fields for that object Im getting the rule error that that value already exists… it exists but for that same object so it shouldnt be a problem, right?

    Nevermind. Fixed.

  • #317 / Feb 19, 2010 12:29pm

    bobosayhello

    11 posts

    DMZ looks a nice ORM for CI and I am going to use it. But I have some questions in my mind after some documentation reading.
    That is, why does DMZ require the use of an extra joining table even when there is just a one-to-many relationship between two tables? What’s the problem with the traditional approach of having a foreign key in the table of ‘many’ and making it refer to the primary key in the table of ‘one’?

    We can hardly avoid having an extra joining table for an M:N relationship between two tables. But of course it can be avoided for a 1:N relationship. I believe there has to be some reasons behind this design in DMZ and I would love to know more about it. By the way, I would also like to know if this design affects database performance much.

    Any thoughts on this are very welcome.

  • #318 / Feb 19, 2010 12:35pm

    NachoF

    171 posts

    It doesnt require a join table… just for n to n relations

  • #319 / Feb 19, 2010 2:05pm

    NachoF

    171 posts

    I just ran into a weird problem.
    Im trying to store the user object in the session after logon.

    But for some reason when I try to access its properties elsewhere in my app I get

    Message: Trying to get property of non-object error

    Yet, Im sure the object is created just fine and simply stored in the session.

  • #320 / Feb 19, 2010 2:35pm

    Oblique

    32 posts

    @NachoF

    I think you should describe situation in more details, i’m not Phill, but looks like he won’t be able to help you.

    Also, if you want to access users in dmz-style, like an object, you maybe should store only user id in session, and create user object in constructor of controller ancestor like i did here: WISDOOOM
    (forgive me self-advertising 😊 )

  • #321 / Feb 19, 2010 2:46pm

    Oblique

    32 posts

    At the same time, i encountered some strange behaviour
    On my dev WAMP this worked fine (MYSQL ver. = 5.0.45 if it matters somehow):

    $this
                ->where('role', 'carrier')
                ->where('activated', '1')
                ->select('id, username, email, permissions, created, activated, role')
                ->include_related('user_profile', array('id', 'company_name'), 'profile')
                ->include_related_count('created_freightage')
                ->get($limit, $offset);

    but in production LAMP (MYSQL ver. = 5.0.89) it made this crap:

    You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘`users_subquery`.id = `users`.`id`) AS created_freightage_count FROM (`users`) L’ at line 4

    SELECT `users`.`id`, `users`.`username`, `users`.`email`, `users`.`permissions`,
     `users`.`created`, `users`.`activated`, `users`.`role`, `user_profiles`.`id` AS profile_id,
     `user_profiles`.`company_name` AS profile_company_name, 
    (SELECT COUNT(*) AS count 
    FROM (`freightages`) LEFT OUTER JOIN `users` 
    as creator_users ON `creator_users`.`id` = `freightages`.`creator_id` 
    
    //why `` here??
    WHERE creator_`users_subquery`.id = `users`.`id`) 
    
    AS created_freightage_count 
    FROM (`users`) LEFT OUTER JOIN `user_profiles` as user_profiles 
    ON `users`.`id` = `user_profiles`.`user_id` 
    WHERE `users`.`role` = 'carrier' 
    AND `users`.`activated` = '1' 
    LIMIT 10
  • #322 / Feb 19, 2010 3:46pm

    OverZealous

    1030 posts

    That is, why does DMZ require the use of an extra joining table even when there is just a one-to-many relationship between two tables? What’s the problem with the traditional approach of having a foreign key in the table of ‘many’ and making it refer to the primary key in the table of ‘one’?

    As mentioned earlier, it does not require an extra table.  DMZ handles In-Table Foreign Keys, which it says on the first page of the manual 😉, as well as under Database Tables (see the bottom).

    DMZ is based upon the older DataMapper by stensi, and his design required full Fifth-normal form compliance.  Obviously that has negative performance and database complexity side effects, which was one of the original factors for forking DataMapper.  (Well, is it really a fork if the original has not been updated?)

    There is an awesome new release coming soon (probably early next week), but the changes are mostly performance and new-features based, so the upgrade from 1.6.2 to 1.7.0 should be very smooth.

  • #323 / Feb 19, 2010 3:51pm

    OverZealous

    1030 posts

    But for some reason when I try to access its properties elsewhere in my app I get

    Message: Trying to get property of non-object error

    I’m guessing you are coming across this error or you have a database field name or related field that overides a Reserved Name.

    (There’s a reason for the list at the top of the Troubleshooting page.)

    Remember, there are no namespaces in PHP (<6.0), which means there can only be one class per name.  This means that you cannot have a model named Session if you have a library named Session.  (MY_Session and CI_session are OK, though.)

  • #324 / Feb 19, 2010 3:53pm

    OverZealous

    1030 posts

    @Oblique

    It looks like your LAMP server has an outdated version of DMZ.  Make sure all of the files are synced.  The subquery-based bug you are seeing was fixed in 1.6.2.

  • #325 / Feb 19, 2010 4:04pm

    NachoF

    171 posts

    Heres my login function

    function login()
            {
            $u=new Usser();
                if($_POST)
                {
                    $login=$this->input->post('login');
                    $password=md5($this->input->post('password'));            
                    if($u->where('login',$login)->where('password',$passsword)->get()->exists())
                    {
                        $this->session->set_userdata('user', $u);
                        //print_r( $this->session->userdata('user'));
                        redirect("welcome");
                    }///more stuff after this but not relevant
  • #326 / Feb 19, 2010 4:11pm

    OverZealous

    1030 posts

    @NachoF
    :ahhh:
    You can’t put a DataMapper object into the session!  That would store:
    - Two copies of the entire Object, each of which references
      - All of the data that DMZ uses to manage the object:
      - The entire CI DB object
      - The entire CI Language object
      - The entire CI Loader
      - Probably much, much more
    - Now recursively apply this to every related object that is loaded on that User.

    If you have any autoloading, this could actually cause an infinite loop.

    Just store the ID of the user in the session, and pull it from the database each time.  It’s a ridiculously fast query, since it is a primary key lookup.

    (If the session is not in the database, then make sure the cookie is encrypted!)

    PHP is completely stateless, so there is really no practical way to store objects between requests.

  • #327 / Feb 19, 2010 4:15pm

    NachoF

    171 posts

    Ok, I just thought that it would be more practical to store the complete object in the session.. I just came back to CI after working in asp.net mvc and just thought I would use the same approach of storing the complete logged in user object in the session instead of just the id… but that would do. thanks

  • #328 / Feb 19, 2010 4:26pm

    OverZealous

    1030 posts

    @NachoF

    I understand completely.  I used to write code almost exclusively in Java, and Java servers also have sessions with long-term in-memory objects.  (Plus they have that cool way of storing the session ID inline in the URL, so it works without cookies.  But I digress…)

    But even so, the way DataMapper works, it might not be very sensible on that kind of server, because the DMZ model retains connections to the database, among other objeects.  Also, you would then have to worry about stale data (ie: the user changes their name, and now the session model is incorrect, etc).

    Just a hint: I extend the CI Session class to handle loading my user automatically.  Basically, after the session is initialized, you can then see if a User ID exists, and if so, load the User automatically, and store it on the session object.  If you want to use lazy-loading, do it like this:

    class MY_Session extends CI_Session {
        ...
        function get_user() {
            if(!isset($this->_logged_in_user)) {
                $this->_logged_in_user = FALSE;
                if($this->userdata('userid') !== FALSE) {
                    $u = new User($this->userdata('userid'));
                    if($u->exists()) {
                        $this->_logged_in_user = $u;
                    }
                }
            }
            return $this->_logged_in_user;
        }
    }

    Usage:

    if($this->session->get_user()) {
        // logged in
        echo "Welcome " . htmlspecialchars($this->session->get_user()->name);
    } else {
        // not logged in
    }
  • #329 / Feb 19, 2010 11:33pm

    BaRzO

    105 posts

    Hi all, I haven’t do this
    a have a model region and a region can have many city and a city can have one region…

    my database
    citeis table
    id | name | region_id

    regions table
    id | name | status

    city model => var $has_one = array(‘region’);

    region model => var $has_many = array(‘city’);

    how i can pull all regions and regions cities
    like this

    regions a
      |____ city 1
      |____ city 2

    region b
      |____ city 4
      |____ city 9

    pls help me i haven’t figure it…

  • #330 / Feb 19, 2010 11:53pm

    OverZealous

    1030 posts

    @BaRzO

    You might be able to do it in a single query, but you have to think about it backwards:

    $city = new City();
    
    $city->include_related('region', array('id', 'name', ...));
    $city->order_by_related('region', 'name', 'ASC'); // order by region first
    $city->order_by('name', 'ASC'); // then by city name
    $city->get();
    
    $last_region = NULL;
    foreach($city as $c) {
        if($c->region_id != $last_region) {
            $last_region = $c->region_id;
            // output region info
            echo($c->region_name);
        }
        
        // output city info
        echo($c->name);
    }

    The next release of DMZ has a method to specifically handle large queries, which might be useful if you have a lot of cities.

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases