Welcome Guest, Not a member yet? Register   Sign In
IgnitedRecord 1.0 pre-release

[eluser]Cannyp[/eluser]
Hi there,

I have a table with a composite unique index on 2 columns. When I insert a row into the table, if the keys already exist, IR bombs out and gives me the error:

Code:
Query error: Duplicate entry '1000-1001' for key 2

This is as expected. However, I want to be able to trap this error (as I expect it to happen often by design) and continue on with my program flow and alert the user that the key exists.

Is there any way to stop IR from bombing out at this point? Can I wrap it up in a try/catch somehow (I've tried this and it doesnt work and dont want to go messing with the IR code)

thanks again
Martin

[eluser]m4rw3r[/eluser]
The error is not generated by IgnitedRecord, it is the database class that is printing an error from your database.

From what I understand of your problem: why not check if they already exist before you try to insert it?
Because your db complains if you try to insert a duplicate PK.

About exceptions: That is a no as long as IR is PHP 4 compatible.

[eluser]obsesif[/eluser]
Cool datamapping library, i am really thankful, that someone took the initiative to start such an important layer.
As a novice database-user, it is a bit painful to me to understand the configuration alternatives.
I started first with models, then tried YAML and now preferring on-the-fly generation. But each has its quirks. I really wish the documentation would be a bit simpler. Especially, the customisation of table-names, is a bit problematic. My tables used con_tablename method, where the prefix describes various general usage (like auth_ for authorisation stuff, loc_ for localisation, con_ for content related). I tried to create cross tables, according the rules described (like con_items_con_persons) which gets wierd somehow. After adding the cross-tables and preparing some simple join's -even with the table-name settings, I got stuck. Table names, model names and object names got easily overlapped, resulting with false prefixes on the ID fields (e.g. it tried to use on_items_con_persons.item_id where it should use on_items_con_persons.con_item_id). I ofcourse had all tables named accordingly, used the settings array on creation etc.

The settings table/name/field_id aren't easily understandable, there should be one example for each. It is slow to try figuring out various methods.
Also the singular/plural methodology is a bit weird, i prefer to name the table names plural and the models singular. But this feature, combined with the _ names, gets easily problematic.
As a novice user, I also get troubled, when I see examples like
habtm:
name: projects
join_table: project_assignments
without some detailed descriptions.

Of course, it is painful, to create the library, prepare the docs and give support at the same time. I wish, I could help you anyhow to write examples at least, but my knowledge is limited to what I gathered from expoerimentations with the clues (not description) I saw on the docs.

I wish, that this library gets a fully-fledged alternative database-layer for CI. I am open to some restrictions (like dropping PHP4 for sake of faster development). But the possibilities should be much better documented. This library would push the whole CI much further, as CI is about speeding the development process... Again, thanks a lot and looking forward for the final release of 1.0 (following the SVN, surely).

note: after some thoughts, i believe a global setting for prefixing table/field names would be an ideal solution for me and similar-minded users.

[eluser]obsesif[/eluser]
I've found another question... If I use the on-the-fly generator like

$this->person = IgnitedRecord::factory('persons');
$this->person->habtm('items');
$this->item = Ignitedrecord::factory('items');
$this->item->habtm('persons');
$this->item->has_many('images');
$this->image = IgnitedRecord::factory('images');
$this->image->belongs_to('items');

do I have to create these relations each time I'm gonna use them on each controller? I could create a parent controller, to create just these and put each specific job into child controllers. But I've got tens of relations on my database, wouldn't these disturb each other (when viewed them as chained sets)? Is there an easier way to do these?

[eluser]louis w[/eluser]
Does this support updating the related items, or just listing them on select?

[eluser]m4rw3r[/eluser]
@obsesif and everyone:
I'm currently beginning with a complete rewrite of the manual, so I'll try to make everything more clear.
Among other things I'll be updating in the manual is how the defaults are generated, because it seems like it is a bit unclear, and I'll also reevaluate the terminology I use.

@obsesif:
Yes, you have to do it on every request (you can write it in MY_controller or in a helper or some other file you load in each controller).

@louis w:
What do you mean? If you mean you want to be able to edit objects which has been fetched with related() or join_related(), then it is definitely possible.
All objects which have a model linked to them can be saved.

[eluser]Muser[/eluser]
Is it possible to assign an object to a IgnitedRecord object?

I want to assign an avatar object to an user ignitedrecord object, an access it like:

$user->avatar->url();


At this moment, I neet to instantiate the avatar object with a factory method Sad :

In the controller:
Code:
$user =& $this->user->fetch($this->auth->user['id']);

        $data['user'] = $user;
        $data['userdetail'] = $userdetail;
        // I need to pass the avatar object separately for every user object
        $data['avatar'] = Avatar_model::factory($user);

User IR model
Code:
class User extends IgnitedRecord {
    var $belongs_to = "province";
    var $has_one = "userdetail";

    const NICKNAME_MIN_LENGTH = 4;
    const NICKNAME_MAX_LENGTH = 12;
    const PASSWORD_MIN_LENGTH = 4;
    const PASSWORD_MAX_LENGTH = 25;
    const EMAIL_MAX_LENGTH = 30;

    public function fetch($id)
    {
         $this->join_related('province','name');
         //$this->join_related('userdetail');
         return $this->find($id);
    }

}

Avatar NON IR model

Code:
class Avatar_model extends Model {

    var $user;
    var $image; //temporary file from upload temp

    const AVATAR_PATH = '../media/avatars/';
    const URL_AVATAR = '/media/avatars';

    public static function &factory;($user)
    {
        $obj = new Avatar_model();
        if(is_object($user))
            $obj->user = $user->id;
        else
            $obj->user = $user;
        return $obj;
    }

    public function load_data($data = '')
    {
        if(is_array($data))
        {
            $this->user = $data['user'];
            $this->image = $data['image'];
        }
    }

    public function exists()
    {
        return file_exists(APPPATH.Avatar_model::AVATAR_PATH.$this->user.".jpg");
    }

    public function url()
    {
        return base_url().Avatar_model::URL_AVATAR.'/'.$this->user.".jpg?rnd=".random_string('nozero',6);
    }

    public function thumb_url()
    {
        return base_url().Avatar_model::URL_AVATAR.'/'.$this->user."_thumb.jpg?rnd=".random_string('nozero',6);
    }

    public function save()
    {
        $CI =& get_instance();

        $config['image_library'] = 'gd2';
        $config['source_image'] = $this->image['tmp_name'];
        $config['new_image'] = APPPATH.Avatar_model::AVATAR_PATH.$this->user.".jpg";
        $config['maintain_ratio'] = TRUE;
        $config['width'] = 240;
        $config['height'] = 300;

        $CI->load->library('image_lib', $config);
        $CI->image_lib->resize();
        
        return TRUE;
    }
}

And another question... is it possible to get related tables like "province", without using the fetch() method i've created in User model?

Like on Rails, only with User $belongs_to province, and province $has_many User, i can't get it done. Or Every time I want related data I need to do a join_related?

[eluser]Muser[/eluser]
Is this a better aproach?

I've included avatar model in user model file, and inside fetch() method, when I get ignitedrecord object, I'm calling load_data() to load the avatar object.


Code:
<?php

// I've included avatar model
include APPPATH.'models/avatar_mode.php';

/**
* Description of user
*
* @author Administrador
*/
class User extends IgnitedRecord {
    var $belongs_to = "province";
    var $has_one = "userdetail";

    const NICKNAME_MIN_LENGTH = 4;
    const NICKNAME_MAX_LENGTH = 12;
    const PASSWORD_MIN_LENGTH = 4;
    const PASSWORD_MAX_LENGTH = 25;
    const EMAIL_MAX_LENGTH = 30;

    public function __construct()
    {
        parent::__construct();
    }

    public function fetch($id)
    {
         $this->join_related('province','name');

         $obj = $this->find($id);
         if($obj == FALSE) return FALSE;

         $obj->load_data(array('avatar' => Avatar_model::factory($id)));
         return $obj;
    }

}
?>

[eluser]Muser[/eluser]
[quote author="Muser" date="1228796143"]
And another question... is it possible to get related tables like "province", without using the fetch() method i've created in User model?

Like on Rails, only with User $belongs_to province, and province $has_many User, i can't get it done. Or Every time I want related data I need to do a join_related?[/quote]

Sorry for repeating the question Tongue

I've got the solution here --> http://ellislab.com/forums/viewreply/487421/

[eluser]m4rw3r[/eluser]
That would work nicely, as long as you want to use only your own fetch() method.
But if you want to have an avatar instance for all objects instantiated by that model, it would be better if you put it in the find_by() method, because get() and find() uses find_by() to fetch data.

Example:
Code:
// in the model
function &find;_by($column, $data = false)
{
    $obj =& parent::find_by($column, $data);

    if( ! $obj)
        return $obj; // $obj = false

    $obj->avatar = Avatar_model::factory($id);

    return $obj;
}
Note: The code above only instantiates avatar objects when get(), find() and find_by() are called.

If you want to have the same for the find_all() and find_all_by() methods, put similar code in find_all_by().

Or you can also add it as a Child class helper (which ALWAYS will be instantiated, even with join_related()):
Code:
// modify your avatar object to use the constructor,
// to be able to receive a record instance:
class Avatar_model extends Model {

    var $user;
    var $image; //temporary file from upload temp

    const AVATAR_PATH = '../media/avatars/';
    const URL_AVATAR = '/media/avatars';

    // constructor, replaces the factory
    function Avatar_model(&$obj)
    {
        if(is_object($obj))
            $this->user = $obj->id;
        else
            $this->user = $obj;
    }
// ...

// add the helper class to your model:
class User extends IgnitedRecord {
    var $belongs_to = "province";
    var $has_one = "userdetail";

    // 'prop name' => 'class name'
    var $child_class_helpers = array('avatar' => 'Avatar_model');
// ...
No modifications are needed to the methods (but you can add the extra join_related() as I described above with find_by().




Theme © iAndrew 2016 - Forum software by © MyBB