UnionOfRAD / lithium

li₃ is the fast, flexible and most RAD development framework for PHP
http://li3.me
BSD 3-Clause "New" or "Revised" License
1.22k stars 237 forks source link

Singular model names? #301

Closed nwp closed 12 years ago

nwp commented 12 years ago

What is the thinking around plural model names? I see a mix of singular vs. plural in different li3 projects but the li3 create model command generates plural models names. I'm assuming some thought has been put into this decision but I'm curious as to it's origin as it seems to be in conflict with the idea that a model typically represents a noun or resource that is usually related to a single row or document.

gwoo commented 12 years ago

Models represent collections. Whether they be a collection of rows, docs, keys, objects etc. Collections are by nature plural. You can find one row, document, key, etc on a collection. Collections are nouns and nouns can be plural or singular, as in $posts = Posts::all() or $post = Posts::find($id). However, to use a singular form you must receive it from the plural form. To operate on the singular form you use an instance, $post->save(), $post->delete(), wheras operations on the plural form are static, Posts::update(), Posts::remove. In other words, if you want to modify a row, document, key, object, etc, use an instance method. If you are going to modify the who collection, use a static method. Static methods are also useful when accessing characteristics of the entire collection, whereas instance methods are useful for accessing a particular property of the row, document, key, object etc, as in Posts::tags() would give you all the tags used in all the posts, and $posts->tags() would give you only the tags for that row, document, key, object, etc.

daschl commented 12 years ago

As an addition to @gwoo's answer: we changed to plural not so long ago, so older project may still use the old notation!

nwp commented 12 years ago

If this was changed recently can someone point me to the debate that ensued when this change was proposed? I would assume this would be a pretty big debate since it is inconsistant with most other interpretations of models across the framework/language landscape (models are singular in Cake, Fuel, CI, Kohan, Yii, Propel, Doctrine, Django (Python), Rails (Ruby), JDO (Java), EJB (Java), Hibernate (Java), Spring MVC (Java), NHibernate (.NET), .NET MVC (.NET), Backbone.js (JS), Ember (JS), CoreModel (iOS/Objective-C) etc.)

daschl commented 12 years ago

@nwp if you think of it, @gwoo's answer is pretty sane and in my opinion the plural approach for relations and collections makes sense. I can't think of a discussion here on github, but you can search the irc logs.

Actually, if you want to use singular models go for it. You just have to change the class name if you autogenerate it. Lithium doesn't mind how you name your models, just make sure you reference them correctly in your controller.

nwp commented 12 years ago

@daschl the plural approach for relations and collections does make sense, but a model is neither--it is a singular entity that may be a member of a collection or relationship. This distinction is not trivial nor semantics--it is fundamental to what a model is and what role it should take in an application.

As you mentioned, it appears that singular models were indeed the convention previously, but it was changed in March of 2011. Can anyone detail the thinking behind this change?

Anyway, I'm not trying to be difficult, as I honestly want to know if I should assume that Lithium models are somehow different than what I'm used to in other languages and frameworks. In my estimation, if plural models names made sense then everyone would use plural names. As I pointed out previously, however, virtually no one has plural model names--they are almost exclusively singular across the entire software development landscape.

Finally, the point about Lithium not enforcing the plural convention is understood and I'm leaning toward using singular model names in our application. Before I do so, however, I'd like to hear the underlying reasoning for making them plural and breaking with a well understood convention used in other frameworks.

gwoo commented 12 years ago

I believe I already provided that reasoning.

nwp commented 12 years ago

And I believe I illustrated why that reasoning if faulty and inconsistant with every other MVC framework and ORM in popular use today. Models simply are not plural--data access components are often plural, but these are called models for a reason.

And BTW, the take it or leave it attitude is not encouraging. I'm at the early stages of adopting Lithium company-wide for a Quantcast top 500 website that gets 13 million page views per month. I was hopeful that we could work together to improve both the quality of Lithium and the adoption of good patterns and best practices. It appears that I may have miscalculated if you're not open to an honest discussion on a fundmental issue where Lithium is inconsistent with other frameworks.

gwoo commented 12 years ago

Lithium allows you to use singular or plural. You asked for the reasoning behind plural and I spent time to provide you a thoughtful answer. I'm not sure what more I can do.

nateabele commented 12 years ago

Hi @nwp, thanks for considering Lithium. Being the one who actually made the convention change, I'd like to make a couple points here: first, while many people prefer singular (for table names, in this case), clearly the issue is far from settled: http://stackoverflow.com/questions/338156/table-naming-dilemma-singular-vs-plural-names

...that reasoning [is] faulty and inconsistant with every other MVC framework and ORM...

Populist arguments have no technical merit. Many people doing a thing does not inherently increase the validity of said thing. Lithium was the first framework to provide model support across relational databases, MongoDB, CouchDB and others through a consistent API, so there is no one set convention that applies across the board. Honestly, the change was made for no other reason than code with plural model names reads more fluently to my brain.

Actually, to your point about CakePHP, we were thinking about changing it to plural there, too, but Cake enforces on you much more in terms of its conventions, so the change would have been too onerous at the time it was contemplated. As you've noticed, Lithium enforces no convention on you other than how it generates model classes by default.

It appears that I may have miscalculated if you're not open to an honest discussion on a fundmental issue where Lithium is inconsistent with other frameworks.

I'm not sure how I feel about this statement other than confused. We're extremely fortunate to have a highly productive community engaged in solving genuinely interesting problems. When I consider it, I suspect that this is correlated with the fact that we specifically don't quibble about inconsequential, surface-level issues.

Lithium was designed with the very clear intention that we're not better than you are at predicting your needs. Every time you generate a new application, it comes with over a dozen files that bootstrap the framework and wire its components together. We specifically hand these files over to people so that they can configure (or not) the framework to operate however they'd like. We have precious few conventions that are taken as gospel. Again, this is intentional, in part to avoid useless bickering.

As with many "standards" debates (see: tabs vs. spaces), there's no clear winner, and whichever one you use isn't important: it's preference. The important part is that you (your team, etc.) picks one and uses it consistently.

nwp commented 12 years ago

@nateabele I very much appreciate the response.

wheelsandcogs commented 11 years ago

Apologies for reviving this discussion after more than a year but just wanted to add my 2p for anyone else who comes across this issue via Google.

Having recently started using Lithium I had exactly the same question, and I believe the answer here is that the Model in Lithium takes a slightly different approach to other ORMs, which might throw people at first.

If you look at Propel or Doctrine (and most other ORMs), then the Model is generally split into two classes, where one class is an instance of an individual record, and a second 'peer' or 'table' class provides a way to query for or manipulate collections of the former.

In Lithium there is only one class - if you want to run queries then you use the static methods, which return collections of instances of the same class. I imagine this was done as an attempt at simplification but it does seem to break the "Separation of Concerns" principle.

It might help if this was made slightly clearer in the documentation so that developers coming from other ORMs aren't immediately confused by this difference.

mackstar commented 11 years ago

@wheelsandcogs

Lithium models follow the 'Active Record' pattern, not the 'Data Mapper' pattern such as Doctrine ORM or Propel, the response even though is a collection of results are broken down into sensible 'seperate concerns' handled by their own respective classes. This is similar to how 'Active Record' works in 'Ruby On Rails'. A different approach but equally as valid!

But good documentation is always a bonus as you suggest!

mackstar commented 11 years ago

@nwp

Singular or Plural? I feel it is one of the lesser issues to be bothered about when you have the choice anyway! I used to use Singular when using Rails and even was around when the switch from Singular to Plural happened in Lithium and it didn't affect me or any application architecture one bit. I am happy with either. Pick one and stick with that.

I feel either works just as well as the other and it is pretty much down to choice.

jails commented 11 years ago

Since fab503bf92af65bc7102897f93b71f60673a886d the "autogeneration" is no more pluralized by default even. So you can choose your prefered convention. Both naming should works fine.