Welcome Guest, Not a member yet? Register   Sign In
Suggestion for best practice models
#1

[eluser]Hyra[/eluser]
Hey hey,

I've got a quick question to the "best practice" of arranging my model/library cluster. Or at least some opinions, hopefully.

In short:
I'm re-arranging the code for ArtInvolved.com (currently 100% CI ignited)

Lenghtier:
I'm struggling a bit with the way I want to implement the "Browsing functionality". An Artwork has a lot of data to it. The actual artworkdata such as Location of the image and title, but it has a lot of additional data underneath it: Comments, Statistics, ArtistData, etc.

Now, currently I've got one model (Artwork_Mdl) which pretty much handles, well, everything.
It contains methods like:
Code:
get_comments(); // To retrieve the array of comments
get_stats(); // Views, Rewards, Was it featured, etc.
find_by($what, $dir); // Part of the method collection to browse

This, obviously, gets a bit bloated, and contains a lot of methods that query other tables (user table, log table, etc.) to retrieve the additional info.

While this works OK i was wondering if I should maybe split the model up into a few little models that query the other tables specifically, and, for the sake of usability, have a library that the controller can call, which in turn asks questions to the different models.

A little braindump, for the purpose of "how to display the Latest Additions':

- I create a library "browser"
- This "browser" can be called from the controller with: $this->browser->latest_additions();
- The library invokes an Artwork_Mdl, which returns the basic data such as the ID, title, artistID and the location of the image for the X latest addtions.

This is simple enough. Now, same for a specific artwork:
- The library invokes Artwork_Mdl and requests the data for a specific ArtworkID
- The library invokes the Comment_Mdl and gets all the comments for it
- The library invokes a Stats_Mdl and gets the statistics
- Etc.

Now, adding a new comment ..
- Library has a function "add_comment"
- Library invokes the Comment_Mdl and stores the new comment

As you can see this can get very messy too. In fact, the browser library becomes the Artwork_Mdl the current version uses, but acts as an intermediate, therefore increasing code rather than trimming it down.

I do apologize for the incoherent rambling. It's just that it's unclear to me what approach I should go for, therefore can't really explain Smile

Any help/suggestions/thoughts will be highly appreciated!
#2

[eluser]Jondolar[/eluser]
I don't see a problem having multiple functions in one model class to handle all of the typical queries that you would need to populate a page of artwork (art info, comments, stats, etc). I think that the strict way is that a model is supposed to handle data for one object type. Your "artwork" has info, comments and stats so it makes sense to me.

It looks like your "browser" class is performing functions of a typical controller but I don't have much info on that.
#3

[eluser]Hyra[/eluser]
Thanks Jondolar,

it just felt like I was ending up with a "super object" that holds too much children.
Then again, a Forum would be pretty much the same. The forum model should handle forums, topics, replies, talk to the user table for poster-info.

So in a way it makes sense.

I feel a bit more at ease now and will continue with the first mentioned way (without the extra library).

Cheers.
#4

[eluser]Michael Wales[/eluser]
artwork would be one class that would hold your generic information (title, file, uploaded_date, author_id, etc).

comments would be another class that would handle your comment retrieval, comment posting, editing, etc.

rewards would be another class that would handle reward retrieval, reward receiving, etc.

Basically, think of your site as a group of objects sitting on a table. Each unique object should be its own model: a piece of artwork (maybe even the paint, aka: the file that creates that artwork), a reward, a few comments, a list of locations that artwork can be seen, a user that created that artwork, etc.
#5

[eluser]Hyra[/eluser]
That would ideally be the best. I agree.

But that would mean a lot of extra code in the controller.

For instance, showing the 8 latest additions (artworks) on the homepage would require something like:

Code:
$this->load->model('artwork');
$this->load->model('artist');
$this->load->model('comments');
$this->load->model('stats');

// get the latest additions
$LatestAdditions = $this->artwork->find('latest')->limit(4)->get();

// Find who posted them
$this->artist->get_artist_ids(&$LatestAdditions);

// Find the comments (to show how many per artwork)
$this->comments->get_comment_count(&$LatestAdditions);

// etc. etc.

This gets very lengthy, and since on 80% of the ArtInvolved.com pages artworks need to be shown, in different groups (Recommended Artworks, Related to current artwork, More artwork by artist), it will be a lot of repetitive code as well.

Using one "mother object" the code in the controller can be reduced to something like:

Code:
// Controller
$this->load->model('artwork');

$LatestAdditions = $this->artwork->find('latest')->limit(4)->get();

The model, in turn, then does all the other work that is described in the first bit of pseudo code. It will load everything up, find the belonging Artist-data, comments, etc. and then returns the whole lot as an object

Again, I do see the point of trying to get every model/object as capsulated as possible, but it seems to defeat the purpose if you need to rewrite a lot of code all the time.

Unless .. i DO use the intermediate "Browser Library" which translates the controller request into a lot of calls to different models.
#6

[eluser]Michael Wales[/eluser]
Just because you have a model dedicated to a particular table doesn't mean you can't access that table from other models. You are absolutely right, for a homepage you want the author and a comment count.

Code:
$this->db->select('artwork.id, artwork.title, artwork.file, COUNT(comments.id) AS comments, user.username', FALSE);
$this->db->join('comment', 'comment.artwork_id = artwork.id');
$this->db->join('user', 'artwork.user_id = user.id');
$this->db->order_by('created_on', 'DESC');
$this->db->get('artwork', 4);

But, let's say the user is viewing a single piece of artwork. You would have one call to the artwork model to get the data on that piece and one call to the comments model to retrieve the comments.

In my experience my data retrieval methods are developed to do exactly what I know I will need (like above, getting comment count and username) where as my data input methods are much more closely tailored to that specific object.
#7

[eluser]Jondolar[/eluser]
IMO, when you are working with the artwork info, your artwork model should get artwork, comments, etc. When you are working with the comment info (add/edit/delete), that would be a different model. The artwork model should handle everything related to artwork that is not redundant in another model. The comment model should do the same.
#8

[eluser]Hyra[/eluser]
I'm going with that last approach (Jondolar).
Seems the best way to get things done and, more importantly, find things back.

The ideal world is Michaels, but less workable. At least at this time. Or for me.

Thanks for the feedback. ArtInvolved.com should get his new release soon Smile




Theme © iAndrew 2016 - Forum software by © MyBB