Welcome Guest, Not a member yet? Register   Sign In
Probably a php-related question..
#1

[eluser]stormbytes[/eluser]
So as the title says, this is probably a php-related question, but being an avid CI addict I figured I'd post it here, seeing how terrific the crowd has been about helping me out!

I'd like to create a a Model called 'stacks', which has a method called 'Rows'. Now I don't know if this would be a 'subclass' of if I'm really even using the right term, but what I'm trying to do is make it so that 'Rows' has its own properties/methods.

For instance:

Code:
$Stacks->name

Would be a property of 'Stacks' class.

Then:
Code:
$Stacks->rows->count()

Would return the 'count' of the 'rows' object.

I hope I'm explaining this adequately. I'm not sure how to work it... If someone would be kind enough to post a sample snippet of how to declare this 'subclass' (or at least that's what I'm calling it!) that would be grand -

Thanks!
#2

[eluser]LuckyFella73[/eluser]
Hi Daniel,

if all you want is to count the rows of the query you did before
you can use the active record class and the build-in methods for that.
For example:
Code:
$this->db->count_all_results();

Maybe I just didn't understand what exactly you want to do, then I'm
sorry ..
#3

[eluser]stormbytes[/eluser]
Done some Googling. Pretty sure what I was asking was related to aggregation/composition in general.

Will have to find some tuts on the subject. Google's not my friend today.
#4

[eluser]WanWizard[/eluser]
For a model called $Stacks, you would have to load it manually, since CI would load it as $this->stacks.

Then, when you want to use $Stacks->rows->count(), rows is an object as well, which you could load in your stacks model using
Code:
// in your stacks model
include APPPATH. 'models/rows.php';
// assume rows.php contains a class called rows
$this->rows = new Rows();

You can even do this in one model file if you want
Code:
Class Stacks extends Model
{
    function __construct()
    {
        $this->rows = new Rows();
    }

    // more code here
}

Class Rows
{
    // your code here
}
#5

[eluser]stormbytes[/eluser]
Wow! Now that's encouraging! Smile

I spent the better part of the last two hours scouring all kinds of php resources relating to 'composition' and 'aggregation'. Talk about a brain-drain. I mean, it's all good stuff but right now I need to focus on my development project and your approach cuts right to the chase. I didn't realize I could assign a (child) object as a property of a parent-object, in the way you describe. This makes life a LOT simpler Smile

So basically..

I create my parent object, in this case "Stacks". I can then assign other objects as 'properties' of Stacks, using $stacks->prop = new $rows. How cool is that!?

Question:

Assuming "Rows" requires it's own arguments, could I simply do $stacks->rows = new Rows($args) ?
#6

[eluser]WanWizard[/eluser]
Yes.

This is by the way exactly what CI itself does when classes are loaded, where do you think '$this->modelname' comes from? ;-)
#7

[eluser]stormbytes[/eluser]
[quote author="WanWizard" date="1287526743"]For a model called $Stacks, you would have to load it manually, since CI would load it as $this->stacks.[/quote]

Fuzzy on that last bit. Could you clarify what you mean by loading it manually, and perhaps, why?
#8

[eluser]Watermark Studios[/eluser]
...meaning that you would have to do
Code:
include APPPATH. 'models/stacks.php';
to use $Stacks directly. Otherwise you can just use CI's $this->stacks->rows(Args). Treat rows() as a method of the Stacks class that instantiates a new object for Rows. Personally I would do it the CI way like this:
Code:
Class Stacks extends Model {
  var $CI;

  function Stacks ($config = array()) {
    $CI =& get_instance();
    $CI->load->Model('Row');
  }

  function row ($args = '') {
    return $row = new Row($args);
  }
}
Or something like that. Obviously you could have the row method return an array of objects or how ever you want to handle it. This way you maintain the CI load method and not have to manually do anything.

Hope this helps,

Ken
#9

[eluser]stormbytes[/eluser]
Man.. I'm still missing something - I just don't get the mechanics of this, and so I'm playing guessing games.

Here it is in actual context:

I've got a Model called "Assets_mod". I'd like to assign Catalog_mod to the 'catalog' property of Assets_mod.

So.. Here's Assets_mod:


Code:
if (! defined('BASEPATH')) exit('No direct script access');

include APPPATH. 'models/catalog_mod.php';

class Assets_mod extends Model {
    
    public $catalog;

    function __construct() {
        parent::Model();
    }
    
    function catalog() {
    
      $catalog =& get_instance();
      $catalog->load->model('catalog_mod');
      
      return $catalog = new Catalog();
    }

}

Then, here's my Catalog_mod:

Code:
if (!defined('BASEPATH')) exit('No direct script access');

class Catalog_mod extends Model {

    function __construct() {
        parent::Model();
    }
    
    function test() {
      echo "It works! - The catalog generated this!";
    }

}

And in my controller, I'm trying to call the 'Catalog' method of the Assets model like so:
Code:
$data['catalog']        = $this->assets_mod->catalog->test();

I'm getting errors all around so obviously I'm just not grasping the principle of what's happening here.

Sad
#10

[eluser]danmontgomery[/eluser]
You never call catalog()...

Code:
if (! defined('BASEPATH')) exit('No direct script access');

class Assets_mod extends Model {
    
    public $catalog;

    function __construct() {
        parent::Model();
        $this->catalog = $this->catalog();
    }
    
    function catalog() {
    
      $catalog =& get_instance();
      $catalog->load->model('catalog_mod');
      
      return $catalog = new Catalog_mod();
    }

}

Unless you're doing this multiple times, I would probably just:

Code:
if (! defined('BASEPATH')) exit('No direct script access');

class Assets_mod extends Model {
    
    public $catalog;

    function __construct() {
        parent::Model();

        $CI =& get_instance();
        $CI->load->model('catalog_mod');

        $this->catalog = new Catalog_mod();
    }
}

However, this is largely unnecessary... When you load a model, it gains access to all models and libraries already loaded, so in your controller, if you:

Code:
$this->load->model('catalog_mod');
$this->load->model('assets_mod');

// You can:

$this->assets_mod->catalog_mod->test();

// Which is the same as:

$this->catalog_mod->test();

Of course, this doesn't work if $this->assets_mod->catalog_mod needs to be a different instance than $this->catalog_mod.




Theme © iAndrew 2016 - Forum software by © MyBB