CodeIgniter Forums
Just a little explanation for a beginner... - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forum-20.html)
+--- Forum: Archived Development & Programming (https://forum.codeigniter.com/forum-23.html)
+--- Thread: Just a little explanation for a beginner... (/thread-22971.html)

Pages: 1 2


Just a little explanation for a beginner... - El Forum - 09-25-2009

[eluser]knucklehead[/eluser]
Hello!
I am getting started with CI, just as with MVC approach... So, please tell me if I understood the logic of all this correctly;

Let's say I have a relational database full of artists and events for a club. I would like to get clean URLs at the end, something like last.fm style
www.blah.com/artists/NAME
www.blah.com/events/EVENTNAME
etc.

So, I should start with creating models for db queries, right? Let's call it artistsModel.php;
Code:
<?php
class ArtistsModel extends Model{
    
    function ArtistsModel(){
        parent::Model();
    }
    
    function getAllArtists(){
        
        $query = "..."; // some query to get all artists
        
        $data = $this->db->query($query);
        
        return $data->result();
        
    }
    
    function getArtist($AID){
        
        $query = "..."; // some query to get one artist
        
        $data = $this->db->query($query);
        
        return $data->result();
        
    }
    
    // etc.
    
}
?>
Ok, if I make var_dump of this result, I will get an array full of objects (each object is exactly one row from my query). Is this ok?

Also, my results are now not 'grouped'. I wonder if I should do 'grouping' in my controller or my view?
What I mean by that? If an artist has more than 1 link to their website i will get more than 1 row of that artist from db. So I should make each artist another 'object' with 'formatted' properties before I start to manipulate with him, right? I imagine my object would look like
artist_name = string
artist_description = string
artist_links = array()
artist_countries = array()
...
And all my artists should look like that...

So, should I create those objects in controller or view?

If I make a controller like this:
Code:
class Artists extends Controller{
    
    public $artist_ime;
    public $artist_zemlja = array();
    public $artist_links = array();
    public $artist_opis;
    public $artist_priority;
    
    function Artists(){
        
        parent::Controller();
        
    }
    
    function index(){
        
        $this->load->model('artistsModel');
        $data['artists'] = $this->artistsModel->getAllArtists();
        // should I create my objects at this point already and send them instead of 'raw' data?
        $this->load->view('artists', $data);
        
    }

}
I will maybe use the same code for 'grouping' in a few places, which somehow seems wrong to me...
Should I make some programming to define an artist 'object' in controller and another programming in view to loop through my objects?
I also wonder which datatype should be $data here? Should it be also an array of objects? Because right now, if i var_dump($data) I get an array with 1 value and it is called 'artists' which is actually an array of my rows... Is that ok?
If I make some programming and create objects inside of controller, how should I 'pack' my results and send it to view?

Uf, I am sorry for all the confusion and I know this is some extremely basic and beginner stuff, but I started with OOP few weeks ago and I am still a little bit confused about everything...

Any suggestion/advice/help is extremely welcome! =)

Thanks!


Just a little explanation for a beginner... - El Forum - 09-25-2009

[eluser]jedd[/eluser]
Hi knucklehead and welcome to the CI forums.

A couple of things that might help - it's a big message you've posted there with a fair bit of stream of consciousness going on Wink

First, CI libraries and helpers stick with the underscore separator, in preference to the camel case thing. Personal preference, of course, but if you're not fussed, consider flipping now, early on.

Grouping - do it in your model. If you might want to group differently, either have a private model method that does the actual call and work, and a few 'public' model methods that do subtly different things - or just use an additional parameter to your method in your model, such as defining the grouping, ordering, etc aspects.

You might also be more comfortable with returning your data as arrays rather than objects - this is what I do, and I find it a bit easier on my brain. The functions are pretty similar, and are documented next to the object-returning functions in the manual.


Just a little explanation for a beginner... - El Forum - 09-25-2009

[eluser]jdfwarrior[/eluser]
What he said..


Just a little explanation for a beginner... - El Forum - 09-25-2009

[eluser]knucklehead[/eluser]
Hi and thanks for quick replies and warm welcoming =)

I am used to write with camel case, but yes, I have noticed those underscores all around source code and I will listen to your advice and switch, before I actually start with everything!

Grouping in model - ok, I can make what you said - group it in model or make some private/public methods. I hope you understand that this is not mysql query grouping, this is actual formatting of my artist object, right... =)
But ok, let me see if I understood you correctly;
in my model:
Code:
function get_all_artists(){

        $query = "..."; // some query to get all artists
        
        $data = $this->db->query($query);
        $a = array(); // this is the 'handler' for each artist
        foreach ($data->result() as $artist){
             // something like
             $a[$artist->artistID]['artistName'] = $artist->artistName;
             $a[$artist->artistID]['links'][$artist->artistLinkURL] = $artist->artistLinkURL;
             // etc.
        }
        return $a;
        
}

...then my controller stays the same as above example (but without properties) and my view gets an $artists array which I format to some HTML. My $artists ends up like an array full of artist arrays, not objects...

Would that be the correct logic?


Just a little explanation for a beginner... - El Forum - 09-25-2009

[eluser]BrianDHall[/eluser]
[quote author="knucklehead" date="1253904378"]...then my controller stays the same as above example (but without properties) and my view gets an $artists array which I format to some HTML. My $artists ends up like an array full of artist arrays, not objects...

Would that be the correct logic?[/quote]

Yup, that's just fine - but you can make it easier on yourself by using CI's built-in ActiveRecord functions. As in:

Code:
function get_all_artists(){

        $query = $this->db->get('artists'); // some query to get all artists
        
        $a = $query->result_array(); // this is the 'handler' for each artist
        
        return $a;
        
}

$a is then an array of all your artists, so in your view you can do a foreach to print out the results all pretty.

If you would prefer to deal with objects you can set $a to $query->result() and then it will be an array of objects. Up to you whether you prefer $artist->name or $artist['name'].

EDIT:

As an extra bit of fun, if you are using PHP5 you can make it a one-liner function:

Code:
function get_all_artists(){

        return $this->db->get('artists')->result_array();
                
}

Code is your worst enemy - the less of it there is, generally the better off you are so long as it is well organized Smile


Just a little explanation for a beginner... - El Forum - 09-25-2009

[eluser]jedd[/eluser]
And yes, if you want to restructure your data - such that you have a 2D array where the first dimension is the artist_id say, as shown, then I'd probably do that in my model - especially if that was what I consistently wanted back from that function.

If I wanted different formatted results, then .. it's a bit less obvious which way to go. You could have a helper function that mungs consistently formatted input into whatever output layout you want, or duplicate your model methods to provide the different outputs, or a private function within your controller (especially if the scope of this problem is a single controller).

Not to rain on BrianDHall's appreciation of objects, but in response to your 'array of array's question/example above, here's what I do for one of my model methods - it might be of relevance:

Code:
function  get_appellations_info () {
        $query_string = "SELECT
                            *
                        FROM
                            appellation";
        $return_array = array();
        $rows = $this->my_get_rows($query_string);      // my_get_rows just wraps some stuff around a basic result_array() call
        if ($rows)  {
            foreach ($rows as $row)
                $return_array[$row['id']] = $row['text'];
            return $return_array;
            }
       else
             return FALSE;
        }

In this particular instance I wanted the key to be the ID and preferred to mung it in the model. I could probably have adjusted my view logic to cope with an array of two-element arrays (id and text). Six of one, in many cases, I suspect.


Just a little explanation for a beginner... - El Forum - 09-25-2009

[eluser]Colin Williams[/eluser]
The model should always return nice, shiny, polished objects to the controller. If your controller starts manipulating data structures too much, it's time to refactor.


Just a little explanation for a beginner... - El Forum - 09-25-2009

[eluser]BrianDHall[/eluser]
See - TIMTOWDI at its finest Big Grin


Just a little explanation for a beginner... - El Forum - 09-26-2009

[eluser]kmil0[/eluser]
for models I always use something like this

Code:
function get($id = null,$limit = null, $offset = null)
{
  if(!is_null($id)) $query = $this->db->where('some_field',$id);

  $query = $this->db->get('table',$limit, $offset);

  return($query->num_rows() > 0 ) ? $query : NULL;

}

Smile


Just a little explanation for a beginner... - El Forum - 10-07-2009

[eluser]knucklehead[/eluser]
Hello everybody! Sorry for a delay, I had some terrible weeks...
I was reading more about MVC pattern and how to use it, and I was reading carefully your posts... I have to thank you all for great tips and explanations!!!! I love CI and I love this forum =)

I was playing with my 'application' for a while and I have few more beginners' dilemmas so please stick with me just a little more =)

OK, my models now look similar to this;
Code:
class Events_model extends Model{
    
    public $event_ID;
    public $event_title;
    public $event_flayers = array();
    public $event_locations = array();
    // some other properties
    
    function Events_model(){
        parent::Model();
    }
    
    function get_event($EID){
        
        $select = "..."; // select
        $tables = "..."; // from
        $where = "..."; // where
        $order = "..."; // order by
        
        $this->db->select($select)->from($tables)->where($where)->order_by($order);
        $data = $this->db->get();
        
        $res = $this->format_event($data->result());
        return $res;
        
    }
    
    function get_all_events(){
        
        $select = "..."; // select
        $tables = "..."; // from
        $where = "..."; // where
        $order = "..."; // order by
        
        $this->db->select($select)->from($tables)->where($where)->order_by($order);
        $data = $this->db->get();
        
        $res = $this->format_event($data->result());
        return $res;
        
    }
    
    // function for formatting results
    
    private function format_event($r){
        $e = array();
        foreach ($r as $event){
            $e[$event->eventID]['eventID'] = $event->eventID;
            $e[$event->eventID]['eventTitle'] = $event->eventTitle;
            $e[$event->eventID]['flayers'][$event->flayer] = $event->flayer;
            $e[$event->eventID]['locations'][$event->location] = $event->location;
        }
        return $e;
        
    }
    
}
Basically, I do some queries here and format query result in some appropriate way...

@kmil0
Your example looks very nice and clean, I will sure try to use it in the near future =)

Then, my controller handles the model like this:
Code:
class Events extends Controller{
    
    function __construct(){
        
        parent::Controller();
        // load some helpers...
        
    }
    
    function index(){
        
        $this->load->model('events_model');
        $data['events'] = $this->events_model->get_all_events();
        // some loop??
        $this->load->view('events', $data);
        
    }
    
    function event($EID){
        
        $this->load->model('events_model');
        $data['events'] = $this->events_model->get_event($EID);
        $this->load->view('events', $data);
        
    }
}
...and finally my view handles the array which was passed from controller... And in some way everything works 'just fine' =)

Anyway, I have two big misunderstandings here;

1) In my model i declared some properties for that model (in my case $event_ID, $event_title, etc.) but I actually never use them... This seems somehow wrong, nah? =) Or maybe I will need them later, when I will try to insert/update my data?? Seems like I am missing something really important here =)

and 2) In my case I have 2 'major' classes: Events and Artists. Both of classes have that method for 'formatting' query (in my case functions format_event($r) and format_artist($r)). In mysql, those two tables (events and artists) are in many to many relation so I have a junction table to handle this.
My final events view (when for example method get_all_events() from model is used) should print out list of all events and within each event list of one or more artists. I don't understand how to link all those fancy-formatted artists (which I made in artists_model) inside of my Events? Should I do it in events_model - to retrieve data with some other method/query (but I cannot call other models from a model, right?), or should I do it in controller - after retrieving all events make some loop (commented line in controller) and associate each artist for particular event here?

I hope I didn't confuse you even more and that you will write some nice posts like before =D

Thanks for any help in advance!