Welcome Guest, Not a member yet? Register   Sign In
Using model in a model
#11

[eluser]wiredesignz[/eluser]
I use a universal base_model which knows nothing but how to CRUD the database.

Extended off that are my business logic models for each table, they modify and check the raw data is valid for the table they represent then pass off to the base_model to save. They also provide feedback to my application when someting goes wrong.

I guess they could be called the service layer.
#12

[eluser]lifewithryan[/eluser]
Yeah I can see that...

I seem to do most of my validation outside the model, but I supposed it doesn't/wouldn't hurt to have a model that knows how to validate itself.

As long as the job gets done right? Smile
#13

[eluser]oribani[/eluser]
I strongly disagree with the notion that a "model" should only encapsulate a database table with simple CRUD operations. As noted in the Wikipedia article, that application layer is intended to do more than simply act as a single database table abstraction. Think about the meaning of the word "controller" -- it should act more as a director rather than being the entire application in and of itself. A "model" *is* a place for business logic. Most large scale applications in fact hold much of their business logic in the database itself (in the form of triggers, stored procedures, foreign keys, etc.).

I think the misunderstanding of what a "model" is is partly caused by the same (over-)hype of "MVC", without carrying with it much understanding of the concepts themselves. Kinda like how empty "AJAX" is, or even more easy, "Web 2.0". For better or worse, plenty of script kiddies have jumped on the MVC wagon, and since the simple howtos and example scenarios don't do much more than tell you to put your database code in the "model", the misuse of that layer as only a database abstraction has become commonplace. Now you read posts all over the Internet calling it "unpure", "dirty", "hackish" to put any business logic in a model. That's WRONG. Misinformed.

The easy example is to think about foreign keys: even if you only want your "model" to be a *database* model, if you want to be "pure", "correct" or what have you, you really should be enforcing referential integrity therein. Thanks to the lack of real foreign key support in MySQL for many years, web applications grew up without anyone worrying about referential integrity at all. Fits the script kiddie lifestyle I guess. Anyhow, for even this simplified view of a model to be able to maintain foreign key validity, a model then has to work with others (or, especially if a framework like CI does not let you do so, you have to write queries to other tables, sometimes duplicating queries elsewhere - THAT is bad style).

Therefore, I believe this to be a shortcoming of CI. I understand that it might not be an easy fix, but it's certainly a disappointing oversight.

So what I did was take the example code above and abstract it into a helper so that I now have a function that works almost identically to the normal $this->load->model() functionality. Here it is (put it into a helper that is auto-loaded and you can use it in any model):

Code:
/**
    *
    * Allow models to use other models
    *
    * This is a substitute for the inability to load models
    * inside of other models in CodeIgniter.  Call it like
    * this:
    *
    * $salaries = model_load_model('salary');
    * ...
    * $salary = $salaries->get_salary($employee_id);
    *
    * @param string $model_name The name of the model that is to be loaded
    *
    * @return object The requested model object
    *
    */
   function model_load_model($model_name)
   {
      $CI =& get_instance();
      $CI->load->model($model_name);
      return $CI->$model_name;
   }
#14

[eluser]wiredesignz[/eluser]
@orbani, Dragging up 18 month old threads is rather poor etiquette, but in any case I think you are confusing Object Relational Mapping (ORM) and MVC Models with your comments about referential integrity.
EDIT:
Nothing in CodeIgniter prevents you from using your own base Model class.
#15

[eluser]oribani[/eluser]
[quote author="wiredesignz" date="1253522617"]@orbani, Dragging up 18 month old threads is rather poor etiquette,[/quote]

Give me a break. That's exactly what the archives are here for. If it's been discussed before, the conversation should continue in a relevant place. That gives it much more context for new and old readers alike.

Good forum etiquette is commonly defined as:

1) If you have a issue, SEARCH to see if someone else has asked about the same problem.
2) If you found such a thread, join in on that discussion where it's most helpful and relevant. NEVER start new threads that re-hash the same thing if at all possible.

The only time the age of a thread becomes relevant at all is when the problem has been fixed or somehow changes in the meantime. That is not the case here unless you can point out otherwise, in which case I'll gladly create a new thread.

[quote author="wiredesignz" date="1253522617"]but in any case I think you are confusing Object Relational Mapping (ORM) and MVC Models with your comments about referential integrity.
[/quote]

No, I'm not confusing anything. YOU are reading too fast. One of my points is actually exactly that - that too many people are confusing the "model" layer of web applications as being merely an ORM layer - the two are NOT the same. Models can and should contain more than ORM logic (but even if you limit it to a strict database wrapper, the foreign key example shows why inter-model code is good practice and should be supported). Show me where I said otherwise. Otherwise, just because you didn't like other threads I wrote, don't just jump on what I say because you feel like you have to prove me wrong no matter what.

[quote author="wiredesignz" date="1253522617"]
EDIT:
Nothing in CodeIgniter prevents you from using your own base Model class.
[/quote]

Kindly explain how that addresses the need for inter-model communication.
#16

[eluser]BrianDHall[/eluser]
@oribani - The only thing I don't understand is how CI is limited, limiting, or fails in some way to support inter-model communication? People incorrectly refer to get_instance() as a hack - it's a very useful, and necessary, feature for any OOP-style framework like CI.

I must agree on Models though, people are concerned with CRUD so much they tend to forget there are other reasons for models to exist. Having an ORM helped me with this, simply because I had this whole empty model that automagically could handle CRUD and all that, so now what was I suppose to do with this model anyway?

What I think is missed is that Models should fully represent the data they are responsible for, including having the brains to know how to deal appropriately with certain manipulations. For instance for a Payment model it should not just know how to store transaction data, but rather should have all CRUD functionality AND be able to intelligently process payments, record the results, and pass on the resulting events to other models and/or back the controller.

So for instance you want to delete a user in a forum - what do you do with their posts? If you want to do a user->deep_remove(), the only logical place to build such functionality is in the user model - where else would you want to put it?

Its a beginners notion to try to put everything in the controller and leave only dumb functions to views and models. Now I see everything should be intelligent - everything has its own mission and requirements, as views 'can' be more than mere templates, and models can be more than CRUD.
#17

[eluser]oribani[/eluser]
[quote author="BrianDHall" date="1253571137"]@oribani - The only thing I don't understand is how CI is limited, limiting, or fails in some way to support inter-model communication? People incorrectly refer to get_instance() as a hack - it's a very useful, and necessary, feature for any OOP-style framework like CI.
[/quote]

You're right, but it's just that it would be nice to be able to do the same thing you do in a controller:

$this->load->model('foo');

Having the extra code suggested at the top of this thread seems a little unnecessary and thus "hackish". That's why I abstracted it into a helper so the model load is a one-liner, which is more clean. Code that is specific to the underlaying CI framework is best hidden away if possible IMO.

[quote author="BrianDHall" date="1253571137"]
I must agree on Models though, people are concerned with CRUD so much they tend to forget there are other reasons for models to exist. Having an ORM helped me with this, simply because I had this whole empty model that automagically could handle CRUD and all that, so now what was I suppose to do with this model anyway?

What I think is missed is that Models should fully represent the data they are responsible for, including having the brains to know how to deal appropriately with certain manipulations. For instance for a Payment model it should not just know how to store transaction data, but rather should have all CRUD functionality AND be able to intelligently process payments, record the results, and pass on the resulting events to other models and/or back the controller.

So for instance you want to delete a user in a forum - what do you do with their posts? If you want to do a user->deep_remove(), the only logical place to build such functionality is in the user model - where else would you want to put it?

Its a beginners notion to try to put everything in the controller and leave only dumb functions to views and models. Now I see everything should be intelligent - everything has its own mission and requirements, as views 'can' be more than mere templates, and models can be more than CRUD.[/quote]

Absolutely! Well said!
#18

[eluser]oribani[/eluser]
[quote author="oribani" date="1253578351"][quote author="BrianDHall" date="1253571137"]@oribani - The only thing I don't understand is how CI is limited, limiting, or fails in some way to support inter-model communication? People incorrectly refer to get_instance() as a hack - it's a very useful, and necessary, feature for any OOP-style framework like CI.
[/quote]

You're right, but it's just that it would be nice to be able to do the same thing you do in a controller:

$this->load->model('foo');

Having the extra code suggested at the top of this thread seems a little unnecessary and thus "hackish". That's why I abstracted it into a helper so the model load is a one-liner, which is more clean. Code that is specific to the underlaying CI framework is best hidden away if possible IMO.
[/quote]

I'd like to add that although CI doesn't PREVENT you from doing things like this, it doesn't prevent you from doing much of anything - it's just PHP, after all.

However, there's a difference between that and SUPPORT. As I hope most people will agree (per most latter posts on this thread), inter-model communication is a good and necessary thing. CI should SUPPORT that as encouraged, good practice. It should be achievable without a hack IMO.

:-)
#19

[eluser]oribani[/eluser]
This article does a nice job of pointing out what a Model really is and hints at the fact that most run-of-the-mill PHP programmers just treat Controllers like glorified page controllers from days of old.

http://blog.astrumfutura.com/archives/37...iated.html
#20

[eluser]Unknown[/eluser]
Hi all,

I get landed on this thread from Google and I am doing the similar practice of calling model from another model. I see you guys had great discussion couple of years back in older CI version and now I am learning Codeigniter 2.1.3 and working on a project which has similar situation for calling model from another model. I am also loading all my model's as autoload.

So my question is will that be safe practice as per current version of CI?

Any input will be helpful. Smile

Kind Regards,
Archit




Theme © iAndrew 2016 - Forum software by © MyBB