I have a domain for users that connects to my user table, which includes information like username, first name, and last name.
Then I have a domain for emails, that connects to the email table because a user can have more than one email. The email table consists of a fk to connect the user with their emails, and other fields like address, status, etc.
Should I have different domains for the separate tables, but combine functions, that call the domains, in the models? Or maybe you can but it's not best practice.
I am new to this MVC thing and it's hurting my brain right now. Maybe, it just someone hasn't explained it well enough.
Question: when you mention having a "Domain", are you referring to a User model, and an Email model? or to the design pattern?
Also, initially (but depends on your application) having the email database logic inside the users model is more logical (to me), since I don't think you are going to add email addresses without creating a user. That is, the email model really depends on the user model, and perhaps only on the user model, so maybe they should be combined?
The way I would do it:
Put all the database logic inside the models which I assume is the way you have done it.
Create a library or class to place the business logic of the application that concerns users. (For example, uploading an image, or connecting to a web service, should not be in the model if you follow the standard that CodeIgniter models should only contain database logic, so that's why I create another class to handle those cases)
Now, when you want to create an user, you just inject the models in the library (you could do this at the controller level), and call your abstract method create_user()
class Users extends Controller {
public function create() {
// these could be in the constructor!
$this->load->model('users');
$this->load->library('users_logic');
$this->users_logic->set_model($this->users);
// and/or: $this->users_logic->set_email_model($this->email_model);
if ($this->input->post('name')) {
$this->users_logic->create();
}
}
}
Related
I know this is a duplicate question but i think it will help others because there are a lot of similar apps that have these kind of table relationships:
So the question is what would be the optimal solution for all relationships in this schema using the Eloquent?
How many Models and Controllers to make?
First of all, you need to understand that not all tables in a database represent an entity.
For example, tables like users, posts, comments are entities. Whereas posts_users, comments_posts are not: they are here for technical reason, to materialize the relation between 2 entities.
Only entities need a model: it makes no sense to have a model for a relation table.
Even if a table holds information like date_created, it does not make it an entity. This is just a data related to the relation. For example, the table users_roles may have a column named date_assigned, to know when a given user was assigned a given role. It's not entitity for all that.
Second, you need to understand what a controller is for. The role of a controller is to handle a request and provide a result. Result can be a view, an error (HTTP 404), or just the fact that an action has been successfully done.
You must also make the difference between the class called Controller (or any child that extends this base class) and an actual controller. The actual controller is the code that will handle the request. A Controller class can have more than one method to handle requests.
It's all a question of organization: generally, Controller classes are used to group methods within the same scope: user login, logout, subscription, password reminder are all the same scope. All these controllers could be in different classes or functions. It does not matter. Each method is a controller. They are grouped in the same class because they have the same needs (check user is logged in, to know if login is required, if subscription page can be displayed, etc.) and they are in the same scope, which just make sense when you think of it. That's just logical: you know where to search when you need to change something about user identification (even if you are new on the project).
So you need a model for these entities:
User
Offer
Invoice
Category
The controllers you'll need depends on what you want/need to do with this data. There's no ready-to-use answer to this part of your question.
Use a Controller class for:
user authentication (if you need some)
user management (backoffice)
invoice management (edit, mark paid, list of late payments, etc.)
categories management (create, edit, delete)
offers management
But depending on your application, you may need more. Only you can really say. There's no bad answer to this question: if you think some controllers should be separated for better organization, do it. If you think you should group 2 or more, do it. There's no rule. You have to keep your code clear and well organized. It must suit your needs. That's all.
I am currently looking to redesign a feature on my web application.
The web application utilizes Yii (version 1) for the back-end.
In this instance I have a model and controller. The model is used to store all the userTracking data and is appropriately a userTracking model however the actual logic for the model is in a controller called UserController. I have a function called actionTrackUser($id) which is used to implement various tracking logic for a particular user and create a model for that user.
I however now need to extrapolate this functionality from the UserController to a seperate trackingController which will implement tracking for various models.
I need to be able to utilize this functionality however in the new controller and old controller. I was wondering as to the best approach for this in Yii 1 that implements MVC correctly. I thought about making a trackingModel and having the userTracking model extend that but then I would have a lot of business logic in a model in order to use it in two places.
I am fairly new to MVC and Yii so I was wondering as to the best approach to take here?
I have purposely left code out of this question as it is more a theoretical question regarding the implementation of such functionality in Yii.
Any help is appreciated.
Thanks!
I am not sure that there may be a 'best' approach. However, you need to choose an approach that works best for you. Be guided by what will work for your situation, and what will make manageable code for you and others in the future.
There is nothing wrong with your current userTracking model and controller. You state that the "actual logic for the model is in a controller." You may want to relook at that to move appropriate data management, constraints and validation rules to the model at least.
You can move functions to a separate trackingController and still use the userTracking model. There is no rules that says you have to have a matching model and controller set, and it is quite possible for a controller to manage more that one model at a time.
I generally start with activeRecord models, which map against data stores (database tables in most cases). I use corresponding Form models to reflect forms that are markedly different from activeRecord models, and I use domain models to reflect complex business objects that are feature rich, and reflect lots of runtime attributes (like calculated fields) and state data (like publish state, which are calculated from other fields - for example a user could have validation status, paid status, active status, account level and so on that all work together to indicate what activity is possible for the user).
I'm making a simple PHP application with Twitter/Facebook integration to practice OOP concepts and patterns, and I need help with how it should be designed.
What my app will do
Basically, once the user logs in, he's show a form with title and body field. When he clicks on "Post", this content will be appropriately transformed and posted to Facebook and Twitter. Of course, he'll also get an option to authenticate my FB/Twitter app if he hasn't already done so. That's what I'm trying to achieve.
The structure I've come up with till now
Since database access will have to be shared amongst multiple files, I'm using a Singleton pattern. Essentially, I have a DB class with a static mysqli link and a static method to get this database link. The models will use mysqli functions with this single link. (I don't want to abstract the database type just yet.)
I have a User class which holds a user's data, like it's id, username and hashed password. It has methods to retrieve user based on id, credentials and even save the current user to the db.
An Auth class manages session and returns a User object for a valid user. So, it manages logging in, and keeping the user logged in between page visits.
The structure I'm having problem with
I now need access to the Twitter and Facebook information of the user. Of course, they'll be in separate tables, and have separate classes to interact with them. But each of this class is associated with a User.
So, when I'm fetching user information from the database, I'll also use JOINs to fetch corresponding data from the Twitter and Facebook table. Then, my plan is to have a Twitter and Facebook object instantiated within my User object. So, these two classes can be accessed as say $user->twitter->post("Something");.
Is this a good structure, or is there a better way to organize classes? This is a simple app, and coding is not my concern. My concern is the structure, since I should be able to add new social networks to the application.
It is preferable to keep persistence functions out of domain objects. Instead of having the User class load and save itself, I would have a UserRepository interface, for example:
interface UserRepository {
public function findUser($username);
public function save(User $user);
}
and a MysqlUserRepository class that implements this interface. That way you keep database-specific code out of the User class.
Similarly, I would pull social networking functions into their own interface, say:
interface SocialNetworkService {
public function post($status);
}
and separate implementations for FacebookService and TwitterService. This allows you to add support for new social networks without having to modify the User class.
These services can then simply wrap around a user object and provide their services for that user:
$fb = new FacebookService($user);
$fb->post("blah");
A common principle behind all of these decisions is the single responsibility principle: your User class should have only one reason to change, and that is when you need to change the model of a user. Any other changes, such as dealing with databases or social networks, shouldn't affect the User class.
I am facing some confusion because i have decided to convert from procedural to oop, I Find it more efficient.
So anyway I've got some questions i hope i find answers here :)
Let's say am working on a php Registeration System which requires
1-Signup process
2-Activation Process
3-Login process (which requires)
Validating inputs
Validating Sessions, etc
The questions is: Should i make class for every process Or i can combine all of them into one class named 'User', with methods to login, signup, activate and so on, Or can i make 1 class named USER which has user's properties, and signup, login classes extends it ?
Should i use separated classes for Sessions, Validating etc ? or just normal Checking inside the main class
Should i Separate ADMIN classes from normal classes ? meaning I have a USER class, which has methods, to login user, signup user etc, should i add more functions for admin like DELETE user, UPDATE user ? or separate it from the normal classes
You should make a User class with different functions for login signup and whatever.
You should separate different functions into as many classes/objects as you feel suits. For instance, with your User class you might have a Session class which you use within your User class to do the session management stuff. You could also create a Person class which User inherits from. This can have functions like printFullName and such, whereas the User class has auth specific stuff like login and register.
Again, its up to you. You can do whatever you want. I would probably have a UserAdmin class which has functions like deleteUser($userid) and editUser($userid) just because then its not confusing it with the auth side of things. However it can be done the other way. You could call a User object for a specific user and call deleteUser() on that to delete the user. Its what you feel most comfortable with.
As with all my answers, its what you want to do. There is no standard to this, and no rules. OOP is mainly about layering everything so that it makes sense, structurally, and about creating reusable code.
Another thing you want to look at is MVC programming. MVC stands for Model, View, Controller. In this set up you actually differentiate objects not by category (e.g. user, page etc) but by their function (e.g. model - connects to a database, view - has the code to layout a page, controller - computes stuff and passes data to the view). If you look at something like codeigniter then this will become more apparent to you.
Now you can create a model for users. In this model you can do all the database stuff, adding, editing, deleting users and such. This can then interface with a controller which will layout the page, e.g. seeing if the user is currently logged in, calling the user's model and getting the name of the user from the model, then passing it to the view to display on screen. This will make much more sense when you start using frameworks like code igniter.
Anyway, good luck in your learning.
It's really your own choice what is in a class and what is not. Mostly it's about what you find to create a good overview and what makes certain use-cases easier. In this case it will most likely cause more confusion if you split these operations, instead of putting them under the same banner.
I'd under most circumstances choose to put validation, signup, etc. in the same class. If admins are also users (and not a whole new table of users for example) I'd also include these in the same class - Or maybe create an admin class that extends the user class.
But there's no ultimate law of what is put in one class and what is not. It's about trial and error and seeing what gives you a good overview, and when you come to building abstraction layers, extending classes, etc. you need to be a little more careful. Taking the right steps can save you a ton of work in later work with extending classes.
I made the switch about 6 months ago from functional to OOP. I read a shitload of papers trying to figure out what the big deal about OOP is.
I think a conceptual understanding is important in this case. Think of an object as a physical thing.
A car:
A car has properties:
color
remaining petrol
top speed
A car has methods:
start
stop
accelerate.
1) A user is an object, login, logout, signup are actions/methods that a user does.
2) A user has session variables(properties) so I would place them as properties in the class
3) An admin user has more methods, but still needs acess to old ones. So idealy an admin user should inherit the properties and methods, I think this is done with the Extends keyword. This is called subclassing, or inhertance.
You best is to google "understanding oop concepts" and read whatever connects with you
I have a User model, with properties (id, username, email, password) and methods (is_unique, get_by_id, save).
As I understand the MVC pattern, my User model has to represent one given user.
So, if I want to get a list of all users, should I implement a method for this in User model, or in a controller?
You would have to build a UserCollection model, containing a collection of User models if you want to do it the proper MVC way. Your controller can never interact with the database directly, hence why we have to create a model ;)
You should make a model class which represent a list of users, e.g. UserList.
Neither of both.
Create a new Model called something like userbaseor clientbase and use it to list users by criteria, retrieve information about your users in general (count, top 10, user of the month, etc...) and for operations that affect a group of users (that may have no direct relation one to another) like building a certain demographic collection of users to send them a mail.
Cheers