Welcome Guest, Not a member yet? Register   Sign In
How to arrange code that updates multiple sql tables
#1

[eluser]gunzour[/eluser]
I'm trying to get the hang of CodeIgniter, really liking how easy it is to do many things. What I'm struggling with a little bit is where is the 'right' place to put code. As in, does a particular piece of code belong in a controller? or a model? or a library?

Here is an example, something I am trying to figure out now. I have two database tables: "building" and "factory". When I create a factory, a row is inserted into the building table (because it is a building), and into the factory table (because it is a factory). The building table has columns that apply to all types of buildings: when it was built, what size it is, etc. The factory table has columns that are specific to factories: what type of good it produces, what its production rate is, etc. The factory table also have a building_id column which is a foreign key to the building table.

There can be other types of buildings, such as apartments, shops, etc., that would each have their own table (with unique columns/properties) with a foreign key to the building table.

The convention in CI appears to be one model per database table. That would mean a "Factory" model and a "Building" model. So if I want to create a factory, I would do the following:

$this->load->model('Building');
$this->load->model('Factory');
$building_id = $this->Building->new_building();
$this->Factory->new_factory($building_id);

That way the foreign key is set up correctly and each row is linked.

Where would I put a code segment like this? In a controller? In a library? Or would I be better off having a single "Building" model that encompasses not only the building table but all of the "sub" tables, such as factory, apartment, shop, etc.?

So far (I'm in the early stages of my project) I've created one model per database table, and everything else is in a single controller. I assume I'll have multiple controllers at some point but it's not really been necessary so far.

I consider myself a decent programmer but my experience is more with procedural code, so I haven't done much with MVC or OO in the past. I'm hoping someone can give some good tips or pointers to good resources to help me figure out the best way to make these kind of design decisions.

Thanks Smile
#2

[eluser]jedd[/eluser]
[quote author="gunzour" date="1243553826"]As in, does a particular piece of code belong in a controller? or a model? or a library?[/quote]

Well, for controller v model questions, you should read up on the relevant sections of the CI user guide, as well as any thing you can find on the MVC approach - such as the [url="http://en.wikipedia.org/wiki/Model–view–controller"]wikipedia article on MVC[/url].

Quote:The convention in CI appears to be one model per database table.

Well, this is one approach, but I'm not sure if it's a convention within CI so much as the way a lot of users (perhaps coming from, or approaching, an AR position) prefer to see things.

I prefer to have a model that manages (is an interface to, etc) several related tables. There's nothing wrong with this approach, and in the case of your factory, apartment, house, and hovel tables, this might make a lot more sense - having a structure model that fronts all these tables.

If you want to use the active record class (as opposed to the built in AR stuff) then you'd need to have a model per table, but otherwise you're not particularly limited in either direction.

There was a discussion a while back on the appropriate (or rather, the average) size of controllers - it was generally agreed that about 300 lines was the size a controller should be, though I don't necessarily agree that if it's bigger than that that you're necessarily doing something wrong there either. As a rough guide for new CI users though it was indicative, and at least should trigger a re-evaluation of the approach - whether bits can be shuffled into separate controllers, libraries, helpers etc - or whether things are just fine with a phat controller. Performance-wise it's arguable if there's any measurable benefit to having the same number of lines of code being distributed amongst multiple files anyway.

EDIT - btw it sounds like your schema is a bit wrong, if you have lots of 'sub-tables' of types of buildings, and a building table as well. Feel free to share your schema if you'd like some input on the design.
#3

[eluser]xwero[/eluser]
I never strictly used the model = table rule of thumb. If a method required a join i added it instead of figuring out how to call another model inside the model, which i think is a a bad practice.
If a model method requires an other models data i load the models in the controller. You have to write more code in your controllers then but if you work with joins you will only need it in exceptional cases.
#4

[eluser]gunzour[/eluser]
[quote author="jedd" date="1243562185"]
I prefer to have a model that manages (is an interface to, etc) several related tables. There's nothing wrong with this approach, and in the case of your factory, apartment, house, and hovel tables, this might make a lot more sense - having a structure model that fronts all these tables.
[/quote]

I like this idea, as you say it sounds like a good fit for the particular situation I'm working on.


Quote:EDIT - btw it sounds like your schema is a bit wrong, if you have lots of 'sub-tables' of types of buildings, and a building table as well. Feel free to share your schema if you'd like some input on the design.

To give you a quick background, this is for a browser-based game. It will be a sim/Tycoon style game with factories that produce goods, shops that sell goods, etc.

In terms of the schema, I was thinking of it in terms of an OO approach. The "building" table could be thought of as a master class, and then there would be a "factory" class that inherits "building", and a "shop" class that also inherits "building". To translate that to a database schema, I figured I would have a "building" table that has properties that would apply to all building types, and then a "factory" table which has properties that only apply to factories, and a "shop" table which has properties that only apply to shops.

This means that a factory would have a row in both the "factory" table and the "building" table. It would always be a 1:1 relationship. But there would also be shops which would have a row in the "shop" and "building" tables, but not in the "factory" table. I guess the alternative would be to put all of the columns I need for all buildings in the "building" table, and leave them NULL in the cases where they don't apply.

Maybe that is not so bad, I think most of the columns will apply to all building types anyway. For all of the subtables, the auto-increment id field from "building" would serve as the primary key, maybe that is a good indication that I am breaking it up more than I need to?
#5

[eluser]TheFuzzy0ne[/eluser]
[quote author="xwero" date="1243596094"]I never strictly used the model = table rule of thumb. If a method required a join i added it instead of figuring out how to call another model inside the model, which i think is a a bad practice.
If a model method requires an other models data i load the models in the controller. You have to write more code in your controllers then but if you work with joins you will only need it in exceptional cases.[/quote]

Slightly off-topic: I'm interested to know how you'd distribute such code. Let's take a forum for example. In my implementation of a forum, the delete thread method calls on the delete posts method. I'm planning on having this app in the form of a library, so users will essentially be in control of how everything works. In a situation like this, how would you handle it so that a user can't delete the posts and forget to delete the thread, or something along similar lines?
#6

[eluser]jedd[/eluser]
[quote author="gunzour" date="1243895997"]
In terms of the schema, I was thinking of it in terms of an OO approach. The "building" table could be thought of as a master class, and then there would be a "factory" class that inherits "building", and a "shop" class that also inherits "building".[/quote]

I think this is going to cause you more pain than it's worth, though I could be wrong. As you later suggest, you are finding much commonality between building types, but you also need to consider the work involved in adding new building types, changing prpoerties to same, and so on. It seems that this approach would require you to modify your schema (usually messy) and consequently some non-trivial changes to your code to facilitate the db change (ditto).

Quote:This means that a factory would have a row in both the "factory" table and the "building" table. It would always be a 1:1 relationship. But there would also be shops which would have a row in the "shop" and "building" tables, but not in the "factory" table. I guess the alternative would be to put all of the columns I need for all buildings in the "building" table, and leave them NULL in the cases where they don't apply.

Think of that as an alternative, rather than the alternative.

Another alternative would be to have an building table that contains precious little - an ID, maybe a name or an address or some player-identifying information if that's applicable.

An accompanying table would contain the attributes of that building. You could indirect that out to have attribute-attribute information defined / constrained elsewhere, but that seems messy considering the scope. I'd stick with the basic two-table approach, and possibly consider constraints in the form of a table that defines your attributes only if absolutely necessary.

Your system will suffer the usual problem of requiring constraints in code, rather than enforced by the database, but there's no easy way around that (and it's not really that much of a problem - just people seem to like their DB to provide boundaries for them).
#7

[eluser]xwero[/eluser]
[quote author="TheFuzzy0ne" date="1243901099"]Slightly off-topic: I'm interested to know how you'd distribute such code. Let's take a forum for example. In my implementation of a forum, the delete thread method calls on the delete posts method. I'm planning on having this app in the form of a library, so users will essentially be in control of how everything works. In a situation like this, how would you handle it so that a user can't delete the posts and forget to delete the thread, or something along similar lines?[/quote]
Sorry for the late reply.

If there is a model method that requires another model method's data it should be documented which data it gets instead of the method because anther developer could get the data from a model you haven't created.

But as i mentioned if you use joins requiring other models data will be rare.
#8

[eluser]gunzour[/eluser]
[quote author="jedd" date="1244039828"]
Another alternative would be to have an building table that contains precious little - an ID, maybe a name or an address or some player-identifying information if that's applicable.

An accompanying table would contain the attributes of that building. You could indirect that out to have attribute-attribute information defined / constrained elsewhere, but that seems messy considering the scope. I'd stick with the basic two-table approach, and possibly consider constraints in the form of a table that defines your attributes only if absolutely necessary.

Your system will suffer the usual problem of requiring constraints in code, rather than enforced by the database, but there's no easy way around that (and it's not really that much of a problem - just people seem to like their DB to provide boundaries for them).[/quote]

Ahh, so the second table would just have 3 columns of, say, 'building_id' (referencing the first table), 'key' and 'value'? Sounds reasonable, it would let me avoid making db changes to introduce new attributes in the future.

Thanks for the help. Smile
#9

[eluser]Andreia M.[/eluser]
I usually arrange my models and controllers acording to what makes the most sense to me. Then again, I'm very new to programming in general and MVC in special, so...
Example: I run a board-based online RPG, which I'm currently re-coding to include CI. In that, thus far, I've thought of:

- a character model, which handles all the stuff relating to the characters: showing a character list, searching characters, adding and updating characters, breeding characters, adding abilities to a character (something that spans 3 tables - characters table, abilities table and character_ability table, since it's a N:N relationship), updating a character's achievement in its class, among other things.

- a player model, which handles all the stuff relating to player information.

Then I have:

- a character controller (which handles all the forms and displaying of character-related info)
- a basic text controller (basically to just serve views for rules and such)
- a basic player controller (which handles all the player-related things)

Does that make any sense? Any tips, ideas, suggestions?




Theme © iAndrew 2016 - Forum software by © MyBB