Part of the EllisLab Network
   
104 of 105
104
DataMapper 1.6.0
Posted: 16 October 2011 05:32 PM   [ Ignore ]   [ # 1031 ]  
Summer Student
Total Posts:  3
Joined  10-15-2011

OK, I change my question; How can I get a row with ORM?

Profile
 
 
Posted: 17 October 2011 02:24 AM   [ Ignore ]   [ # 1032 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  4115
Joined  11-04-2008

Exactly like you did it in your first question.

// create a model instance
$record = new Record();

// get some records
$record->where('field''value')->get();

// loop over them
foreach ($record as $r)
{
    
// echo a column from the record
    
echo $r->field;

    
// get child records
    
$r->child->get();

    
// and echo a field from the first child
    
echo $r->child->field;

    
// store the record in an array
    
$array[] $r->to_array(); // requires the array extension to be loaded

With on ORM you should stop thinking in terms of rows and arrays. A row is an object, and has links to other objects (or more of the same).

I suggest you take some time to go through the documentation. It’s quite extensive, and contains lots of examples. See the link in my signature.

 Signature 

WanWizard.eu | Modular CI, an HMVC solution | DataMapper ORM

Profile
 
 
Posted: 17 October 2011 02:37 AM   [ Ignore ]   [ # 1033 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  4115
Joined  11-04-2008

You will have to get your head around the difference between a CI model and an ORM model.

In case of CI, the Model class is a singleton (there is only one instance) which is accessed via $this->Model, and from a technical point of view behaves just like a library. It contains only reusable logic, no data, which is returned to your controllers for further processing, leading to ‘fat’ controllers.

With an ORM, every instance of data (usually a table row) is a Model object, which encapsulates both the data and the logic as a self-contained entity. All operations on the data, from custom selections, pre- and post processing, to validation, happens inside the model.

The upside of this is that you no longer have ‘fat’ controllers, they are now doing what they should, which is control the flow from request to output, calling the models and loading the views. The upside is also that no matter from which controller you access your data, access is always consistent, as the model will take care of that for you.

Altough Datamapper allows you to keep creating ‘fat’ controllers using code like in the example above (and to be honest, most users use it like that), the idea is that you add custom methods to your Datamapper models that contain the data handling logic.

So in the above example, create a method in your model:

// get an array of id's and fields based on field selection
public function field_to_array($field)
{
    $this
->where('field'$field)->get();

    
$result = array();

    foreach(
$this->all as $record)
    
{
        $result[$record
->id] = array(
            
'id' => $record->id,
            
'field' => $record->field,
        );
    
}

    
return $result;

and then in your controller just use

$record = new Record();
$array $record->field_to_array('value'); 
 Signature 

WanWizard.eu | Modular CI, an HMVC solution | DataMapper ORM

Profile
 
 
Posted: 26 December 2011 07:35 AM   [ Ignore ]   [ # 1034 ]  
Research Assistant
Avatar
RankRankRank
Total Posts:  414
Joined  03-07-2007

Wanwizard, i like the idea of fat models, and i was wondering if extending DataMapper models, when needed, would be an option. Would the next example be problematic in any way for DataMapper model handling?

For example a User model for the front end login etc. and a more extended version with methods for deleting, adding and modifying users. This way you can have an even more leaner model for the front-end and a more extended version for administration purposes or more elaborate data fetching.

// Basic user model
class User extends DataMapper {
  
// validation
  // constructor
  // login_method
  // get_user
// Extended user model, for admin etc.
class User_extended extends User {
  
// call parent::constructor
  // add_user
  // delete_user
  // (can even override or extend the login_method)
  // etc.
Profile
 
 
Posted: 26 December 2011 09:30 AM   [ Ignore ]   [ # 1035 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  4115
Joined  11-04-2008

That should work.

But you might have to see if the autoloader will automatically find the base model. You might have to load it manually.

 Signature 

WanWizard.eu | Modular CI, an HMVC solution | DataMapper ORM

Profile
 
 
Posted: 03 May 2012 01:23 PM   [ Ignore ]   [ # 1036 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  120
Joined  07-18-2011

HI

On your site you have examples for Save. I have a many to many and need to save (its a tags for a blog). But I am confused by your example. You show how to add many to many by creating the Book object by getting books from the database older than year 2000. BUT I am not getting them from a database… my data will be passed with the form (I suspect most peoples would be).

So where you have the following:

$b = new Book();
$b->where('year'2000)->get(); 

How would I put my form submitted values for “books” (in my case tags) into this object, instead of using the where()->get()?

Here is the code I am trying to use. IU have spent ages trying all sorts of ways of doing this.

// Get user foo
$u = new User();
$u->where('username''foo')->get();

// Get a number of books from the year 2000
$b = new Book();
$b->where('year'2000)->get();

// Relate user foo to all the books
$u->save($b->all); 

Thanks a lot

 Signature 

Using EE2 | Amity Web Solutions

Profile
 
 
Posted: 03 May 2012 02:56 PM   [ Ignore ]   [ # 1037 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  4115
Joined  11-04-2008

You’re posting in a Datamapper 1.6.0 thread. I sure hope you’re using something more modern then that! wink

You’re not entirely clear what exactly is posted, but I assume those tags are new entries that needs to be saved and related to something?

If so, then you need to create the tag objects first, populate them with the data posted, save them, and then relate them. You can do that in a similar way:

// array to store the new objects
$objects = array();

// assume tags are posted as an array
foreach ($this->input->post('tags') as $tag)
{
    $object 
= new Tag();
    
$object->tagname $tag;
    
$object->save();
    
$objects[] $object;
}

// relate all the new objects to the parent object
$parent->save($objects); 
 Signature 

WanWizard.eu | Modular CI, an HMVC solution | DataMapper ORM

Profile
 
 
Posted: 03 May 2012 03:08 PM   [ Ignore ]   [ # 1038 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  120
Joined  07-18-2011

Ah sorry about that, I just found what seemed to be the support thread. I am using the current version. I cant see any links on your site to support, is there an official one?

As for the code, thanks a lot. But if I edit a blog now, it saves all the existing tags as new tags, and not updates any. I thought the save handled an update.

Also, is Datamapper intelligent enough to know I have deleted some tags, so to delete the relationships, BUT leave the tags in if used on other blogs, or delete the tags if not used on other blogs? This is the but that got me all confused when using native codeigniter queries and why I wanted an ORM. Otherwise I would still have to write all these functions to check for existing tags and delete or not where necessary. Basically, fully handle many to many relationships.

Thanks

 Signature 

Using EE2 | Amity Web Solutions

Profile
 
 
Posted: 03 May 2012 04:16 PM   [ Ignore ]   [ # 1039 ]  
Sr. Research Associate
Avatar
RankRankRankRankRank
Total Posts:  4115
Joined  11-04-2008

There’s a thread here for every version, a search for “Datamapper 1.8.2” would have revealed this thread as the first result.

No, there is no built-in logic to do ‘diffs’ on input. There are a million possible chunks of application logic related to ORM data, it’s impossible to build it all in.

The best solution is to add a custom method to your Blogs model, which takes the list of tags as input, selects all currently related Tags, and loops over them. If not in the input, delete the relation (or the tag), if present in the input, delete it from the input. After the loop, anything left in the input are new tags, which can then be added.

If this is functionality you need often and for different models, consider writing a generic extension for it, so your new method will be available as an extra Datamapper method on all your models.

 Signature 

WanWizard.eu | Modular CI, an HMVC solution | DataMapper ORM

Profile
 
 
Posted: 03 May 2012 04:44 PM   [ Ignore ]   [ # 1040 ]  
Lab Assistant
Avatar
RankRank
Total Posts:  120
Joined  07-18-2011

Ok thanks. Glad I asked now, I assumed it would take care of it and would have spent ages trying to get it to work.

It is not as simple as deleting what is not in the new post data though, because its a many to many. So the tags may be used on other blogs. So if the tags are not used on another blog, OK to delete, if the tags are used then not ok to delete, and just delete the relationship. So probably not much more coding, but a little. Thing is, this is the trickiest part and why I wanted ORM for many to many.

 Signature 

Using EE2 | Amity Web Solutions

Profile
 
 
   
104 of 105
104