I'm asking for a best practice to create an adhoc model. I want to create a model 'menu' which does not come from a database table but hardcoded in the code instead.
The reason is that i can call the menu model from two different view/layouts.
I tried this as a starting point.
/model/Menu.php
class Menu extends CModel
{
public getMenu() {
return array('home'=>'home/index',
'product'=>'product/index',
'order'=>'order/index',
);
}
}
Do you think this is bad or is there a better way to do this?
Thanks
I think it should be a widget, not model. Or even partial view. Depends on how you going to use it.
I'd suggest creating it as a class just like you did, but I wouldn't extend CModel to avoid the unnecessary overhead. Something like:
class Menu{
public static getMenu() {
return array('home'=>'home/index',
'product'=>'product/index',
'order'=>'order/index',
);
}
}
Related
I'm reworking a project on Laravel 5.1
What I realize is that the old classes have become much complicated and do not really follow the 'single responsibility' principle anymore.
So I'm planning to do such:
<?php
class User extends Model
{
}
class SocialUser extends User
{
}
So I have a few questions,
Is it possible to achieve that?
If yes, then does the SocialUser class link back to the same database table which is Users and would it conflict with the User model itself?
Is this all a good design practice at the first place? Or I better make use of traits?
Thank you.
What you’re doing (extending the User model) is perfectly fine, and an approach I use myself in projects.
For example, if an application I’m building has shop-like functionality, then I may create a Customer model that extends my User model, and contains say, order-related relations:
class Customer extends User
{
public function orders()
{
return $this->hasMany(Order::class, 'customer_id');
}
public function worth()
{
return $this->orders()->sum(function ($order) {
return $order->total();
});
}
}
In a recent project, I’ve been working on email campaign functionality and created a Recipient class that extends the User model to add campaign-related methods:
class Recipient extends User
{
public function campaigns()
{
return $this->belongsToMany(Campaign::class, 'recipient_id');
}
}
Because both of these classes extend the User model, I get all of those (and Eloquent) methods:
$customers = Customer::with('orders')->get();
So long as you set the table in your base User model, any classes that inherit it will use that same table, even though the model may be named differently (i.e. Customer, Recipient, Student etc).
IMHO I would go for the Repository pattern. It make's a lot of sense in your situation.
I would do the following:
interface UserRepository {
public function find($id);
public function getAll();
public function create(array $attributes);
public function destroy($id);
//you get the point
}
class CoreUserRepository implements UserRepository
{
//implement the interface rules
}
class SocialUserRepository extends CoreUserRepository
{
//implement the specific logic related to a SocialUser
}
Update
As Mjh described in the comments simply implementing the interface on all UserTypeRepository caused repetition - probably not what you want!
By extending your CoreUser you avoid repetition & maintain a design that will work for your situation.
Although, in your case it could be argued that you are still following SRP because everything in the User model is relating to a user, it's only the type of user which is differing.
Why go for the Repository Pattern?
You are ensuring you have a contractual agreement that all User
Repositories need to implement.
Code is easier to maintain.
Business and data access logic can be tested separately
Should you extend your User model?
Here you are in danger of model pollution. While you can do anything with a model - not everything is a good idea.
Defining relationships on this approach would be a headache due to the confusion caused.
My goal of asking this question is to ferret out whether there are benefits to injecting Controller directly with the data it needs (more specific approach) opposed to injecting a Model into a Controller (more generic approach). Or to establish whether or not it is just a matter of preference.
Injecting Controller with Model:
Model can be used to run all kinds of queries to retrieve various bits of data, but it is a heavier-weight construct than the data itself. Model essentially contains data, or at least it can access all the data you may need. Example:
class CategoryControllerWithModel
{
private $model;
public function __construct($model)
{
$this->model = $model;
}
// generates HTML for input form
public function genHtml()
{
/* retrieve data */
$categories = $this->model->getCategories();
//...
}
}
//instantiation within Factory Method:
class Factory
{
$model = new CategoryModel();
$controller = new CategoryControllerWithModel($model);
return $controller;
}
Injecting Controller with Data:
Here we do a bit more upfront with in the Factory method but we get a leaner Controller that only receives exactly the data it needs and is so completely separated from the Model that it is not even aware of its existence.
class CategoryControllerWithData
{
private $categories;
public function __construct($categories)
{
$this->categories = $categories;
}
public function genHtml()
{
$categories = $this->categories;
}
}
//instantiation within Factory Method:
class Factory
{
$model = new CategoryModel();
//a bit more work to get the data Controller needs
//benefit: Controller not tied to the Model
$categories = $model->getCategories():
$controller = new CategoryControllerWithData($categories);
return $controller;
}
Question:
I suppose MVC stands for exactly that -- Model, View, Controller, so injecting Model is probably considered to be an "okay" thing to do. If so, am I taking this too far by trying to remove Controller dependency on Model?
Suppose I insist that I want to inject Data into my Controllers rather than the Model. Is this a purely preferential issue do you see any concrete benefits of doing so?
From my point of view, Factory shouldn't be responsible for domain logic. It should only be responsible for building things up.
In this case, where you are injecting data, Factory has to know what categories controller is searching for, are there any filtering and so on.
So I think for controller you should only inject model, keep Factory single responsibility only for building things and controller should be responsible for it's data.
I think it's a matter of "separation of concerns" also I do not think that would be a good example of using MVC. I would think more along these lines:
class FooController
{
public function actionView($alias){
$category = Category::loadByAlias($alias);
..... load and render layouts etc .....
}
public function actionList(){
$categories = Category::loadAll();
..... etc ......
}
}
like this the neither the Controller nor the Factory need to know what needs to be done when you load a category nor do they have to handle active/inactive status, even User access ... etc this is all Model Logic, Model can have beforeLoad and afterLoad functions, conditions for listing all categories, eager or lazy loading of related models etc...
In my CodeIgniter project I am using codeigniter-base-model and extending all my models from there.
In my user model I want to ensure that super users don't get included, unless specified otherwise.
Something like:
$this->db->where('uacc_issuper', 0));
And I suspect I can use the observer $before_get for this. But I'm not sure how go about it.
Any suggestions pointing me in the right direction will be appreciated.
in $before_get you have give array of method name called before any get query, you need to add those methods in your child model
class page_model extends MY_Model{
protected $before_get = array('method_name');
function __construct(){
parent::__construct();
}
function method_name(){
$this->db->where('uacc_issuper', 0));
}
}
now if you try to get anything with page model this method will be called every time
$page = $this->page->get(1);
Here's the basic premise, I'm using an active record pattern for db objects, and I think I need some direction how to organize these classes. And also in general how I could potentially split up my class structure. Hopefully I don't explain this too terribly. If composition pattern is the way to go I may need a little hand holding on a way to implement it.
Let's say there's the ActiveRecord base class, at the bottom of the totem pole that deals with mapping objects to the db and the db to objects.
A child of ActiveRecord is a sort of generic User class, that deals with user sessions, logins, encryption of the password field on save and such.
Another child of ActiveRecord is a ActiveRecordButSlightlyMoreAdvanced class. Usually this class has nothing to do with User, but here's my issue.
I want to have a subclass that wants to be essentially a combination of User and ActiveRecordButSlightlyMoreAdvanced; UserButSlightlyMoreAdvanced, without having to copy paste all of the methods from User. It doesn't make sense for User to extend ActiveRecordButSlightlyMoreAdvanced, as it'd require essentially overriding a bunch of methods that have undesirable behavior for User.
It would make sense for UserButSlightlyMoreAdvanced to extend ActiveRecordButSlightlyMoreAdvanced, but I'd have to copy and paste a bunch of methods from User.
I know some people think better with pictures, so here's the structure illustrated.
Base
class ActiveRecord
{
....
}
Child
class User extends ActiveRecord
{
....
}
Also Child
class ActiveRecordButSlightlyMoreAdvanced extends ActiveRecord
{
....
}
The Problem
class UserButSlightlyMoreAdvanced extends User AND ActiveRecordButSlightlyMoreAdvanced
{
:( :( :(
}
I've been thinking about this problem for about a month now and cannot think of a solution that doesn't place burden of maintaining the objects dually if there's a change to how one of them implements saving. I'm going to experiment with a few solutions over the next couple of days and possibly post what I think was best in this situation.
My guess is that you meant to say this:
class UserButSlightlyMoreAdvanced extends User AND ActiveRecordButSlightlyMoreAdvanced
{
:) :) :)
}
If that is the case, look into traits http://php.net/manual/en/language.oop5.traits.php
You might try using the strategy pattern. In this case you would create your class:
class UserButSlightlyMoreAdvanced extends ActiveRecord implements ActiveRecordButSlightlyMoreAdvancedStrategy
{
private $_strategy;
public function useStrategy(ActiveRecordButSlightlyMoreAdvancedStrategy $s) {
$this->_strategy = $s;
}
}
and make your strategy class:
interface ActiveRecordButSlightlyMoreAdvancedStrategy
{
// Define what this should do here
}
Make a strategy class that implements the above interface.
class ActiveRecordButSlightlyMoreAdvanced implements ActiveRecordButSlightlyMoreAdvancedStrategry {
// Do stuff here
}
Now when you call those advanced methods, both classes implement the same interface, but the UserButSlightlyMoreAdvanced class just passes the requests through to the strategy object:
class UserButSlightlyMoreAdvanced extends ActiveRecord implements ActiveRecordButSlightlyMoreAdvancedStrategy
{
private $_strategy;
public function useStrategy(ActiveRecordButSlightlyMoreAdvancedStrategy $s) {
$this->_strategy = $s;
}
public function someSlightlyMoreAdvancedFunction () {
return $this->_strategy->someSlightlyMoreAdvancedFunction():
}
}
Hope that helps.
working on a project at the minute and don't feel the code is as well structured/decoupled/maintainable as it should be.
I think the main problem is using one actions class to do the brunt of the work of my system. But what are the alternatives? My other modules are pretty basic and separate.
Should the model contain more business logic that I have in my controller (at the minute the model file for the actions class in question is more or less empty, the Table model file doesn't have much either).
I was reading http://www.slideshare.net/nperriault/30-symfony-best-practices which has some good points, one of them being avoiding having large actions classes but doesn't really tell you how it should be done.
Should I break up my actions class and have different files in /apps/frontend/module/myModule/lib/. ?
The problem is I have another actions class that has to reuse some functionality from the class mentioned above... I really don't want to have duplicate code an am getting into a bit of a mess.
Some general pointers would be great, thanks
You can either keep all actions in one file, or put each action in its own file.
So, either
class mymoduleActions extends sfActions
{
public function executeIndex($request)
{
// ...
}
public function executeList($request)
{
// ...
}
}
or
class indexAction extends sfAction
{
public function execute($request)
{
// ...
}
}
plus
class listAction extends sfAction
{
public function execute($request)
{
// ...
}
}
It's all in the documentation. You should then put reusable code in a parent XYZAction class that both action classes can extend.
You can always put code in apps/frontend/lib. Create classes that have the code that may be re-used and you can just call the methods from within your actions to avoid duplication