I'm new to Codeigniter and am just learning about the ion auth authentication system. I just have a few questions about it:
1) Is it possible to modify the default users table? (and would you advise for or against it?) I understand that there may be functions in the model, view, library or controller that expect the tables to have their exact default structures but for example, i have no need for a company column, so how can i go about removing it?
2) How can i add additional user information to the default users table? (Will it affect any functions if i just execute some sql to add columns to the default users table?)
3) This is kind of a follow on from theast question, would anyone recommend just creating a separate table for my additional user information and using their user id as the primary key in this new table and then just accessing tjat information via my own models?
Thanks for all your help!
Yes, it's possible to edit the users table, you will, however, have to go through the ion_auth_model / library to check for calls/writes to the field you are deleting. Otherwise you'll experience 500 errors for trying to insert data to a non-existent field.
Yes, you can add additional fields in phpmyadmin where you have access to the database itself. The additional fields will either need to be set to null (to prevent errors on writing if the data isn't present), OR you'll have to include those fields as required and add them to ion_auth's existing functions.
Solid idea, usually the rule I go by is keeping as little null fields as possible in the database. So if every user will have additional information, and you aren't expanding your table to a ridiculous length, then I'd append it to the users table. Otherwise, if you are adding optional additional fields, it's probably better to do an associative table.
Don't forget that you're the developer, libraries are used for convienice and security, but don't feel like you can't tailor them to better suit your needs. That's how we get cookie cutter applications.
Adding/removing fields to the default users table in the database is okay as long as you remove the associated code in Ion Library that depends on it. I encourage you to fork the Ion Authentication library and modify it as it fits your requirements.
If you want to leave the Ion Library unmodified, creating another table to store additional information is the right approach.
For modifying database tables/fields, using CodeIgniter's migration is recommended so that you can keep track of database changes inside a source code repository such as Git.
Related
I want to store some user settings and I thought of 3 options, since it's my first project and I want to start it the right way, I can't figure out which is the the optimal way of doing this..
Storing single settings directly in columns in the user table
Having a user_settings table with the columns setting_name, setting_value and user_id
Storing a JSON string in the user table, in a column named something like "user_settings_json"
On a design analysis, I noticed wordpress stores it in a separate table, but I'm not sure that's necessary for every application (since mine does not have nearly as many user settings as wp does)
I'm using Laravel, PHP, javascript/jquery.
Which do you guys think would be, most useful, overall better, in terms of design, serviceability and performance?
Storing a JSON string ? NO !
You want to be able to isolate the settings, just query what you need. Therefore, keep it in separate columns!
As for the question if you have to make a separate table, no, you don't have to. When you just got some simple settings you can just add the columns to the existing table of users. Be aware of the limitations here. If you do need advanced settings, i would recommend using a separate table. Better do it too early. Not every setting might apply to every user. For example when you've got premium accounts who can have more settings. So, keeping it separate is what I would do.
Btw, I wouldn't let the columns start with 'setting_' if they are already in a separate table containing 'setting' in the name.
Conclusion: Option 2 :)
Recently I've made package for my project which uses Laravel 9 and it allows you to add settings to any Laravel model. It can cast values to primitive types like bool, int, but also to custom classes. Eg.:
$user->settings->get('is_gamer');
$user->settings->set('games_count', 10);
// or global site scoped
Settings::get('display_annoucement');
// more advanced usage with definition of custom class
$address = $user->settings->get('address');
$address->country = 'Poland';
$address->zip = '11-222';
$address->city = 'Warsaw';
$user->settings->put('address', $address);
// any model that implements trait
$article->settings->get('show_breadcrumbs');
$post->settings->get('allow_replies');
You can find it here: https://github.com/npabisz/laravel-settings
I'm developing a page with C5 needing various data to be attached to the user accounts. There are two types of users, having different data. Some of the data is multi dimensional and therefor needs custom DB tables. My question is now if it makes sense to store all data in custom DB tables or to use user attributes for the one dimensional data.
Probably there is no general answer to this, but maybe some pros and cons?
I'm often asking myself where to store data in Concrete5 and would be interested how others decide ...
Yeah. I'd definitely store as user attributes for similar reasons to the one you've already identified (visible, searchable, etc).
concrete5 is extensible, but not super extensible; you can attach data to a user using attributes, but not through some totally custom object / db table that you also expect to, e.g., show up on the user profile page.
Oftentimes in c5 (like any other framework), doing it the Right way (attribute) is more difficult (especially for the first "object", but also for each additional one) than just creating a db table and linking to a user id. But, like in all frameworks, you'll reap benefits down the road that you hadn't even considered. This is in searching, upgradability, and things that might only occur to the guy who takes over development next year.
So, with all that being said, go with attributes. And not just for the one dimensional data. You can configure the attribute controller (and the db schema behind it) to store any data you wish. Look at the Address attribute. This contains multiple fields (though it's still 1D). I think there's an opensource "multi address" attribute out there which stores 1-n addresses as a single attribute. You can do this with an additional linked table, but I've recently gotten lazy with c5 and done no-mysql by dumping json_encode()ed (multi-dimensional) arrays in the "data" field. (In this case, your attribute doesn't even need its own table -- it can use the Default table.) You can then configure the editing interface and also the display value (so, e.g., it just shows a list of each sub-object's Name property). Similarly, you can configure the text that gets indexed for searching purposes.
You asked for pros/cons. Doing this custom will be quicker and more straightforward. Extending an attribute, especially to create something complex, isn't super simple, and there isn't a lot of good documentation. Also, the attribute-editing UI (on the user dashboard page) is a bit kludgy. Yes, you get to "design" whatever you want within the "table cell", but you're still limited to making the admin click on the attribute name, using your editing interface within the cell, and then (ideally) clicking on the little disk icon. (Creating a javascript dialog might solve some issues here.)
I'm hoping to use Ion Auth for a Codeigniter application, but I'm unsure of exactly how to structure the tables appropriately. Basically, I have a few different types of users each with different attributes. How would one build this out with just a single meta table?
Some ideas were offered here ( Create user roles and profiles in Codeigniter using Ion Auth ) but none seem particularly elegant or ideal. Is there a a better way? Can I easily work with multiple meta tables (e.g. meta_type1, meta_type2, etc.) somehow?
A related issue pertains to the "identity" config parameter for login etc. How could I have the identity be email for one user type, and username for another?
Thanks in advance for any tips/advice/ideas
Ion Auth code is really clean and organized.
You can easily hack the login process to accept both username or email. Even better, you can fork the repo on GitHub and make the $config['identity'] variable accept both string or array, and act according to that. And send a pull request! :-)
Regarding meta data for users: I would definitely use a single table to handle users metadata. You can put several columns and set to null in case some user type doesn't need them.
Hope my ideas help! Good luck and happy coding.
I also meet the same problem as you. And i found codeigniter authentication library alternative that could solve the problem. Flexi Auth seems can handle "multiple extra meta table" for different user groups.
I have been tasked with creating an application that allows administrators to alter the content of the user input form (i.e. add arbitrary fields) - the contents of which get stored in a database. Think Modx/Wordpress/Expression Engine template variables.
The approach I've been looking at is implementing concrete tables where the specification is consistent (i.e. user profiles, user content etc) and some generic field data tables (i.e. text, boolean) to store non-specific values. Forms (and model fields) would be generated by first querying the tables and retrieving the relevant columns - although I've yet to think about how I would setup validation.
I've taken a look at this problem, and it seems to be indicating an EAV type approach - which, from my brief research - looks like it could be a greater burden than the blessings it's flexibility would bring.
I've read a couple of posts here, however, which suggest this is a dangerous route:
How to design a generic database whose layout may change over time?
Dynamic Database Schema
I'd appreciate some advice on this matter if anyone has some to give
regards
SWK
I created a very large EVA database years ago (PHP w/ PostgreSQL). It turned out great, but it was large project ($$$). All the forms were completely dynamic, with form/field versioning, publishing workflows, matching dynamic reporting, etc.
EVA basics are easy enough. Getting data in is not the hard part. But form versioning and reporting....you can spend years getting it right.
If I was doing it again today, I would research using one of the newer NoSQL solutions ( http://en.wikipedia.org/wiki/NoSQL#Document_store ). I'd thing about creating a DTO style class that could be passed to a form generator. "Modifying" the form, would actually be modifying the DTO. Then I would persist that DTO into a document/object database.
Also, as you are building your alpha solution, think of how to solve test cases that encompass versioning and reporting needs.
Here is an example of what I mean: A simple "Ask Question form".
Original (version 1): has First,Last,Question
Add email field(Version 2): First,Last,Email,Question
Somebody changes their mind about email: (version 3): First,Last,Question
New marketing guy comes in and changes it: (version 4): Full Name,Email,Question
Now, you need to generate a report (csv). Things get tricky. How do you do it?
We solved this problem with field level versioning with references to their previous versions. Plus the reporting system required the end user to assemble the definition of the report data sources before running. (binding report fields to data fields, etc).
However with the document DB's I'd imagine you can do it differently. I believe the new DB's like CouchDB (others??) have mechanism built in for handling these issues.
Good luck!!
When developing user profiles in my last webapp, I've chosen Key/Value table approach. Here's how my DB design looks:
Users table with fixed columns:
id
login
name
regdate
Users table linked with Profiles table (User HasMany Profile).
Profiles table with different data:
user_id
field
value
This way user can add any additional field to his profile. For example:
user_id = 1
field = 'Facebook'
value = 'http://facebook.com/...'
and
user_id = 1
field = 'Stackoverflow'
value = 'http://stackoverflow.com/user/...'
and so on..
Depending on your needs, it might not be worth even raising the form fields to the "DB fields" level. You could instead serialize these fields in (what is essentially a) dynamic blob and store it in the DB. This is NOT recommended if you have folks who need to query these dynamic fields outside of your app (i.e., the DB design is part of a larger public contract with integrated systems), but if you're just using the app to simply to persist these dynamic fields or if any aggregation/search capabilities within the fields are minor, then I would consider it (esp given CPU capabilities these days). I have used the pattern many times and I have - thus far - never had to refactor. (however, I can understand a case where you might need to).
So I'm working on a framework-esque system with one of my co-workers. Our current challenge is how to best implement statuses. Oftentimes, a status will carry with it unique data (a color for a table row, or text to be displayed to a user. etc). Currently, we have a statuses table which contains all this data. Contained in that table is a column: "css_class", which, whenever a record has that status, the specified CSS class is attached to the element (in this case a tr). Also, in order to assign another record a specific status, a foreign key is specified in that database table (in this case, a user has a specific status. So in the users table, there is a statuses_id foreign key). This implementation works alright, but there are a few problems. First, what if I need to perform a specific action in PHP if a record is in a specific status? The way we do it now is something like this:
if($user->status==0)
{
//execute some code
}
This really doesn't work well if statuses can change. Change one status, and the associated code either breaks or behaves differently than intended.
The other issue, and the main reason for posting a question is that the table contains the column "css_class". This is very versatile and allows us change the style of a specific status very quickly. But we really dislike the idea of putting code inside a database. Perhaps having CSS classes in a database isn't necessarily a bad thing, but I really don't know what the common practice is. Any ideas?
EDIT:
What I've gathered from the first few answers is that I should keep all my view stuff out of my model stuff in order to maintain an MVC framework. My argument is that if I keep the css_class name out of the database, then I'm checking the status id in the view in order to decide which class to assign it. So if I put the class in the database, I'm putting View information in the Model. If I don't put CSS classes in the database then I'm putting Model information in the View (checking which ID it belongs to). So by not muddying up the Model, I muddy up the view instead.......
The most elegant way I've seen this solved so far (and I've worked with a few MVC implementations now) is to store only the relevant data in the database. E.g. you'd store status="red" in the database, and leave it up to the view to know what to do with a red status, in terms of CSS. The problem is then solved by designing a sufficiently advanced View layer that creates reusable structures -- that way you don't need to always be updating things on a page-by-page basis when the css changes.
Passing this information up to the Model somewhat defeats the point of the content/presentation separation, because now your code needs to know to pull presentation information off the database and forward it along to the View level or, shudder, you'll be pulling that stuff from the database right in your View layer code, which makes maintenance a nightmare, as you've now lost control over the information flow.
If you want to continue your paradigm of storing this in the DB, you could make another table that maps VARCHAR names of the statuses to their corresponding INTEGER IDs.
However, if this was my framework. I would not be storing view information like this in the database. This would be handled by the V of my MVC setup.
From a data modelling point of view:
Have a different table for each "kind" of status; keep user statuses separate from page statuses (for example) - group the like entities together.
Don't put the CSS classes into the database, but use some form of status indicator - this could be an ENUM column, if you know the set of possible statuses up front. Transform this into the appropriate CSS class in the view layer. You don't want to end up in a situation where your CSS can't be changed because some data in the database prevents it.