CodeIgniter Forums
DataMapper 1.6.0 - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forumdisplay.php?fid=20)
+--- Forum: Archived Libraries & Helpers (https://forum.codeigniter.com/forumdisplay.php?fid=22)
+--- Thread: DataMapper 1.6.0 (/showthread.php?tid=11358)



DataMapper 1.6.0 - El Forum - 10-02-2008

[eluser]GregX999[/eluser]
Hey, I haven't been able to play with the new version very much yet - too much other work... Sad

But soon!!

Also, I just wanted to say "Don't forget to update the docs." - if you haven't already updated them that is (these ones: http://stensi.com/datamapper/pages/toc.html). One reason I'm really liking both CI and DM is because of the excellent online docs with loads of examples. Be sure you keep those docs up to date for people just finding DM and wanting to see how it's used. I know it sucks writing docs when you could be improving the code, but without those docs, I wouldn't have even given DM much of a look at all.

(Thanks for the mention in the credits... totally unnecessary, but thanks!)

Greg


DataMapper 1.6.0 - El Forum - 10-02-2008

[eluser]hugslife[/eluser]
second that, your docs are very good, which is to say that
they don't look like they were written by a coder :-)

one thing i keep banging my head against, and it's probably
that i'm just thick or doing things bass ackward,
is iterating over an "open ended" list. Say I wanted a list
of the books in my inventory, including JOIN'd authors names.
given tables AUTHORS, BOOKS, and AUTHORS_BOOKS:

Code:
$b = new Book;

foreach ($p->book->get()->author->get()->all as $items) {

echo "ISBN: " . $items->book->isbn . "<br />";
echo "TITLE: " . $item->book->title; . "<br />";
echo "AUTHOR: " . $items->last_name .", ". $items->first_name;

}

produces:

ISBN: 9780755342365
TITLE: 101 Ways to Kill Your Boss
AUTHOR: Roumieu, Graham

The generated SQL:
Code:
SHOW COLUMNS FROM books
SHOW COLUMNS FROM authors
SELECT * FROM (`books`)
SELECT authors.* FROM (`authors`)
LEFT JOIN `authors_books` ON authors.id = author_id
LEFT JOIN `books` ON books.id = book_id
WHERE book.id = 1

Which is correct, exactly what I want, except that my
foreach loop stops there after 1, not continuing down
the list for each book in my inventory.

any suggestions or advice is appreciated!
and again, thanks for all your work with this library.


DataMapper 1.6.0 - El Forum - 10-02-2008

[eluser]stensi[/eluser]
Thanks guys :-) I know how important documentation is as well, so am making a point to update it along with each new version, to reflect the changes made.

@Isuka: Thanks for letting me know. It looks like the same error will occur for strip_image_tags.

@hugslife: The reason it's only doing the one book, is because you're only looping through the authors all list. You can't loop through both the books all list and the authors all list in one foreach loop. You'll need a foreach loop for each all list you want to loop through.

So, here's how I'd loop through all your books, and then show all authors for each of those books:

Code:
// Get all books
$b = new Book();
$b->get();

// Loop through each book
foreach ($b->all as $book)
{
    echo 'ISBN: ' . $book->isbn . '<br />';
    echo 'Title: ' . $book->title . '<br />';

    echo 'Author(s): <br />';

    // Get all authors for the current book
    $book->author->get();

    // Loop through each related author for the current book
    foreach ($book->author->all as $author)
    {
        echo $author->first_name . ' ' . $author->last_name . '<br />';
    }
}

UPDATE

Version 1.3.3 has been released!

View the Change Log to see what's changed.

In short, I fixed some validation rules (those that were overrides of incompatible CI Validation rules) and added in a couple of new validation rules (moved out of the Employee model example since I found them useful for many situations).


DataMapper 1.6.0 - El Forum - 10-05-2008

[eluser]Matthew Pennell[/eluser]
Ignore me, I'm an idiot. :zip:


DataMapper 1.6.0 - El Forum - 10-06-2008

[eluser]Boyz26[/eluser]
Hi I am a little frustrated now so if anyone can help that would be great..

Whenever I do this,
Code:
function date2()
    {
        $person = new Person();
        $person->where('name','Andrew')->get();

        $person->book->get();
        
        foreach($person->book->all as $b):
            echo $b->author;
        endforeach;        
    }

It simply returns all entries from Book. I have not saved any relationships yet, so by right it should not display anything.
Can someone tell me what I did wrong here?

Thank you.


DataMapper 1.6.0 - El Forum - 10-06-2008

[eluser]stensi[/eluser]
@Boyz26: It's hard to know what's wrong without any real context to your issue. Could you show me how you've setup your Person and Book models? If you have no relationships saved then no relationships will be returned by DataMapper so you must have something setup wrong somewhere Undecided


DataMapper 1.6.0 - El Forum - 10-06-2008

[eluser]Isuka[/eluser]
I'm wondering how I can handle validation in the case I have a "has one" relation.

I have something like this :

Client model :
Code:
class Client extends DataMapper
{
  var $table = "clients";
  var $has_one = array("category" => "categories");
  
  var $validation = array(
    array(
            'field' => 'name',
            'label' => 'Nom',
            'rules' => array('required', 'trim', 'xss_clean', 'max_length'=>255)
        ),
        array(
            'field' => 'website',
            'label' => 'Site web',
            'rules' => array('trim', 'prep_url', 'xss_clean', 'max_length'=>255)
        )
    );

    function Client()
    {
        parent::DataMapper();
    }

}

Category model :
Code:
class Category extends DataMapper
{
  var $table = "categories";
  var $has_many = array("client" => "clients");
  
  var $validation = array(
    array(
            'field' => 'title',
            'label' => 'Titre',
            'rules' => array('required', 'trim', 'xss_clean', 'max_length'=>255)
        )
    );

    function Category()
    {
        parent::DataMapper();
    }
    
    function getForDropdown()
    {
      $o = new Category();
    $o->select('id, title');
    $o->get();
    $array = array(''=>'-----');
    foreach($o->all as $row) {
      $array[$row->id] = $row->title;
    }
    return $array;
    }
}

In the case I want insert a new client, I need the name, eventually the website and the category the client belong to. The category is required.
In my view form, I set up an input for the name and the website, and a dropdown menu for the category. How can I make the dropdrown menu required ? Is this handle by DataMapper ?


DataMapper 1.6.0 - El Forum - 10-06-2008

[eluser]stensi[/eluser]
Hmm, well since you're requiring the Category ID when saving a new Client, I'd put an extra validation rule in the Client model.

In Client model
Code:
array(
    'field' => 'category_id',
    'label' => 'Category',
    'rules' => array('required', 'numeric')
)

I'm assuming the drop-down list with your Categories has the Category ID's as the keys, and the Category Titles as the values. Also, that your form post sends the choice as "category_id".

When you save the new Client, you'll need to save the relationship separately. Example:

Code:
// Create client object
$c = new Client();

// Populate client object with user input
$c->name = $this->input->post('name');
$c->website = $this->input->post('website');
$c->category_id = $this->input->post('category_id');

if ($c->save())
{
    // Validation requirements passed (included a Category being chosen) and Client now created

    // Get chosen category
    $cat = new Category();
    $cat->where('id', $c->category_id)->get();

    // Save relation
    if ($c->save($cat))
    {
        // Client now related to category
    }
}
else
{
    echo $c->error->string;
}

I'll be releasing a new version soon that handles the non-Database Table field validation rules a little differently, in that it will have a separate setting so the developer can specify whether the rules for those are run both when creating and updating a record, or just when creating.


DataMapper 1.6.0 - El Forum - 10-06-2008

[eluser]Isuka[/eluser]
Arf i didn't think about adding a fake rule to client model %-P

My controller part is pretty like your exemple so it's work fine.
Is it really not possible to save a relation on an non-existing object ?

It would be really great if I can have a controller like that :
Code:
function edit ($id = '')
{
  $c = new Client();
  if($id) {
    $c->get_where(array('id'=>(int)$id));
  }
  
  if(count($_POST)) {
    foreach($this->input->post('input') as $key=>$val) {
      $c->{$key} = $val;
    }
    $cat = new Category();
    $cat->where('id', $this->input->post('input[category_id]'))->get();
    if ($c->save($cat)) {
      echo 'saved';
    }
  }

  $data = array(
    'client'=>$c,
    'categories'=>$cat->getForDropdown()
  );
  
  $this->view->set($data);
  $this->view->part('content', 'edit_client.php');
  $this->view->load('layout');
}
where the save() method handle the relation on his own.

Also a great feature would be to have the ability to delete a row without the need to make a get() before
Code:
// Exemple : delete a user by his ID
$u = new User();
$u->where('id', 1)->delete();

(Sorry for my bad (very bad) english)


DataMapper 1.6.0 - El Forum - 10-06-2008

[eluser]Boyz26[/eluser]
[quote author="Boyz26" date="1223298057"]Hi I am a little frustrated now so if anyone can help that would be great..

Whenever I do this,
Code:
function date2()
    {
        $person = new Person();
        $person->where('name','Andrew')->get();

        $person->book->get();
        
        foreach($person->book->all as $b):
            echo $b->author;
        endforeach;        
    }

It simply returns all entries from Book. I have not saved any relationships yet, so by right it should not display anything.
Can someone tell me what I did wrong here?

Thank you.[/quote]

My models are as below:

Code:
//models/person.php
&lt;?php
class Person extends DataMapper {

    var $has_many = array("set" => "sets");
    var $table = 'people';
    
    function Person()
    {
        parent::DataMapper();
    }
    
    
}
?&gt;

Code:
//models/book.php
&lt;?php
class Book extends DataMapper {

    var $table = 'Books';
    var $has_many = array("person" => "people");
    
    function Set()
    {
        parent::DataMapper();
    }
    
    
}
?&gt;

Can you tell me what is wrong with it? Thanks again!