There
has been a couple of blogs (one posted at weblog.rubyonrails.com
“Things you shouldn’t do in Rails”) that are stating namespacing
controllers are bad and that you should avoid using them.
This idea does not sit well with me and am curious as to the Rails
roadmap. I’ve seen a couple things demonstrated in examples (Rails
Book, api) that later become deprecated. As others have suggested, a
resource for features/methodologies that are or will be deprecated
would be a very nice addition.
I use controller namespacing and am getting the uneasy feeling
that there is a growing anti-namespacing controller sentiment. I don’t think this would be deprecated, but it could surely go the way of: “not supported - aka we don’t test for that”. To me, this would be very bad as
my authorization code is built to take advantage of namespacing.
For
the following statement: “if your models aren’t namespaced , why should
your controllers be?” (from: http://tinyurl.com/p9odk ) , well I
respond by saying models don’t contain business logic, controllers do.
The duty of the model is to simply provide CRUD methods to your
database. Controllers utilize these models to provide functionality as
the business requires.
I don’t find myself violating the DRY principle by namespacing
controllers, I use partials and lib files to keep it that way. In
fact, putting some functionality into the lib directory has made it
easy for me to utilize the same code in multiple projects.
I would like to see what my fellow railers think of
namespacing controllers and would also like to hear from some of the
rails developers.
Is namespacing a real problem or just something some people think is bad design?
thanks,
andy
p.s. I think I also something about has_and_belongs_to_many on the deprecation list in favor of has_many :though. Is this true?
I would like to see what my fellow railers think of namespacing controllers
and would also like to hear from some of the rails developers.
Is namespacing a real problem or just something some people think is bad
design?
I've been wondering that myself. I've used namespaces before, and
don't really see the problem. I don't know that there's actually any
advantage to the ruby module namespace divisions, but I find that it
makes the code easier to manage by splitting up related files into
subdirectories in the source tree.
p.s. I think I also something about has_and_belongs_to_many on the
deprecation list in favor of has_many :though. Is this true?
Thanks for the response Adam. While I do see the advantages to has_many :through it seems that would be one step further from legacy database integration to deprecate habtm. I only say this because I would think when using has_many :through on a legacy database which would normally be a has_and_belongs_to_many, the names can get confusing.
Before the has_many :through approach was developed I already had a couple of rails apps done using habtm. Table names follow the convention of a habtm relationship. That convention is different with a has many :through. To illustrate (something you already know) instead of subscriptions_users it would be subscribers.
So if habtm would be deprecated my rails databases (done by “old” convention) would considered “legacy” databases and I’ll have to change up my code. Granted the change is minimal, but the names would be confusing (as stated earlier) to anyone following my work. That is unless I change my database table names and refactor my code.
Maybe I’m just picky, but I prefer the correlation between the database tables and models to be very clear and direct.
Now if there is a problem with habtm (of which, I’d like to know), that’s totally different and it should be deprecated. I haven’t run into any issues, but I haven’t used it on “large” datasets yet. If there isn’t an issue other than a convention mindset, then I would suggest leaving habtm.
in a nutshell habtm still has it’s place, I don’t think their are any
plans of deprecating it. has_many :through is not a replacement to
hatbm.
I agree it isn’t a replacement, which is why I was confused.
If you are going the RESTful route, I think namespacing starts to not
make sense. For example, instead of having a Articles controller and
corresponding Admin::Articles controller for your administrative
backend, you would keep all your CRUD operations in your Articles
controller and restrict access to the actions accordingly.
In practice, I don’t know. I’m still using namespacing, although I also
have some duplication between controllers.
–
I honestly haven’t done enough research on REST and it’s usage within rails. A lot of people have said good things about the approach. I need to get a better understanding of this methodology. It seems more complicated and possibly error prone to group admin functions with public functions in a single controller. Forgetting or incorrectly restricting access to a method seems more likely to happen than restricting access to an entire controller. Yeah, I know that’s what testing is for, but I’m only human and make mistakes. I just like to make it harder for me to make these mistakes.
Thanks for the response Adam. While I do see the advantages to has_many
:through it seems that would be one step further from legacy database
integration to deprecate habtm. I only say this because I would think when
using has_many :through on a legacy database which would normally be a
has_and_belongs_to_many, the names can get confusing.
Before the has_many :through approach was developed I already had a couple
of rails apps done using habtm. Table names follow the convention of a
habtm relationship. That convention is different with a has many :through.
To illustrate (something you already know) instead of subscriptions_users it
would be subscribers.
This is an underlying change that doesn't need to be made. The
structure is still the same, and you can just tell rails to use a
different underlying table for the relationship.
As usual, I take issue with the assertion that if you use the
configuration options to tell rails to do something other than the
default naming convention magic, that you're somehow "not using rails
anymore".
If you're making a new app, use the convention names. If you're using
an old app, tell rails what names you used or refactor.
Does it need to be more complicated than that?
So if habtm would be deprecated my rails databases (done by "old"
convention) would considered "legacy" databases and I'll have to change up
my code. Granted the change is minimal, but the names would be confusing
(as stated earlier) to anyone following my work. That is unless I change my
database table names and refactor my code.
Maybe I'm just picky, but I prefer the correlation between the database
tables and models to be very clear and direct.
That's why it makes more sense to have an explicit model for the
relationship using has_many :through.
Now if there is a problem with habtm (of which, I'd like to know), that's
totally different and it should be deprecated. I haven't run into any
issues, but I haven't used it on "large" datasets yet. If there isn't an
issue other than a convention mindset, then I would suggest leaving habtm.
Personally, it's always seemed like an ugly construct to me, and
doesn't accurately model the way I've been making relational databases
for the past ten years.
I never made the assertion you mentioned, so I’m not sure what you are taking issue
with. It’s not complicated, but just because some people think a
design or code (to generalize) is ugly doesn’t mean it’s automatically
incorrect or inefficient. Beauty is in the eye of the beholder.
Explicit models are useful when there are attributes associated to the
relationship, but I’ve been doing this for a while myself and have
rarely required this implementation.
Do you define all your relationships that could be habtm with has_many :through even if there aren’t additional attributes associated with the relationship?
> Personally, it's always seemed like an ugly construct to me, and
> doesn't accurately model the way I've been making relational databases
> for the past ten years.
>
>
I never made the assertion you mentioned, so I'm not sure what you are
taking issue with.
No, nor did I mean to imply that you did. I was arguing pre-emptively
against a point that's come up in the past.
It's not complicated, but just because some people think
a design or code (to generalize) is ugly doesn't mean it's automatically
incorrect or inefficient. Beauty is in the eye of the beholder.
Explicit models are useful when there are attributes associated to the
relationship, but I've been doing this for a while myself and have rarely
required this implementation.
Do you define all your relationships that could be habtm with has_many
:through even if there aren't additional attributes associated with the
relationship?
I do, for several reasons:
1) When I design databases, I prefer to have every table have a
primary key. has_many :through supports that for mapping tables,
and HABTM does not. This is just one of my rules, and it's served
me very well in the past. Relational tables without primary keys
make me nervous, and I've never encountered a situation where
having a primary key was a drawback. If you have one, I'd love to
hear about it.
2) You never know when a relation is going to acquire additional
attributes. Adding attributes is easy if you've got the model
already, but converting a HABTM relationship to HMT is somewhat
less easy. In fact, a fairly large number of my relationships do
have additional attributes, since I frequently want to put audit
timestamps on when the relationship was created/modified.
When I design databases, I prefer to have every table have a
primary key. has_many :through supports that for mapping tables,
and HABTM does not. This is just one of my rules, and it’s served
me very well in the past. Relational tables without primary keys
make me nervous, and I’ve never encountered a situation where
having a primary key was a drawback. If you have one, I’d love to
hear about it.
Still have the primary key on the habtm, it’s just not a singular key.
You never know when a relation is going to acquire additional
attributes. Adding attributes is easy if you’ve got the model
already, but converting a HABTM relationship to HMT is somewhat
less easy. In fact, a fairly large number of my relationships do
have additional attributes, since I frequently want to put audit
timestamps on when the relationship was created/modified.
The possible addition of attributes is a good point. I especially like the point about audit timestamps.
The duty of the model is to simply provide CRUD methods to your
database. Controllers utilize these models to provide functionality as
the business requires.
100% incorrect. Models contain business logic. Controllers deal with the user’s request and work with models to transmit views. Don’t believe me? Take away your controllers and views and then go use your models with a different front-end.
From http://java.sun.com/blueprints/patterns/MVC-detailed.html
The MVC architecture has its roots in Smalltalk, where it was originally applied to map the traditional input, processing, and output tasks to the graphical user interaction model. However, it is straightforward to map these concepts into the domain of multi-tier enterprise applications.
Model - The model represents enterprise data and the business rules that govern access to and updates of this data. Often the model serves as a software approximation to a real-world process, so simple real-world modeling techniques apply when defining the model.
View -The view renders the contents of a model. It accesses enterprise data through the model and specifies
how that data should be presented. It is the view’s responsibility to maintain consistency in its presentation when the model changes. This can be achieved by using a push
model, where the view registers itself with the model for change notifications, or a pull model, where the view is responsible for calling the model when it needs to retrieve the most current data.
Controller - The controller translates interactions with the view into actions to be performed by the model. In a stand-alone GUI client, user interactions could be button clicks or menu selections, whereas in a Web application, they appear as GET and POST HTTP requests. The actions performed by the model include activating business processes or changing the state of the model. Based on the user interactions and the outcome of the model actions, the controller responds by selecting an appropriate view
Who am I to argue with java blueprint? Yes, you’re right models do contain some business logic and that statement was incorrect, but let’s continuing reading on your referenced page:
Re-use of Model components. The separation of model and view allows multiple views to use the same enterprise model. Consequently, an enterprise application’s model components are easier to implement, test, and maintain, since all access to the model goes through these components.
Easier support for new types of clients. To support a new type of client, you simply write a view and some controller logic and wire them into the existing enterprise application.
Increased design complexity. This pattern introduces some extra classes due to the separation of model, view, and controller.
I believe point one is referring to taking away the controllers and views and reusing with a different front end. IMO, points two and three are good examples of why namespacing is useful. Let’s not forget namespacing controllers requires a matching view path with Rails. Nice and neat organization.
Other than pointing out my woefully incorrect statement, you didn’t provide an opinion on namespacing controllers. Which is what I was really after…
Do what works for you, freeze the version of Rails that supports what you are doing, and ignore the rest. Don’t ask ‘how high?’ when DHH says ‘jump’ in a screencast. (This is not an accusation, just an opinion of how to deal with the issue.)
There are daily discussions about namespaced controllers on IRC, “how?” and “should I?” and “they don’t work” and “you’re an idiot”. In the meantime I’m using them without problems. Many projects partition nicely into user and admin sections, and I namespace the controllers to reflect this. Moving some code into lib/ keeps things DRY, and it’s easy to put authorization on the whole admin namespace. Namespaces are important (see changes in Rake commands over last few Rails versions for verification of this) and are integral to the way Rails works… they’d have to seriously go out of their way to deprecate the use of namespacing in controllers, it’s not worth the work and it wouldn’t improve anything, unless we’re really talking about RestRails or DoWhateverDavidDoesRails.
And before I get my ass chewed off for having an opinion, I’m a David fan. His RailsConf talk was very good regarding understanding your problem domain and making models that reflect it well. This was deep understanding that can help many people. Then he started talking about REST, and suddenly a bunch of people that had working nonRest apps were on IRC getting help for their now non-working REST apps. Why?
Namespaces rock. I use them all the time, There’s no reason why you shouldn’t use them. And if they disappear, you are always welcome to make a plugin to support them once again. I plan to do that when they deprecate push_with_attributes from habtm so I can still support legacy databases.
However, namespacing’s need has been reduced somewhat. It’s nice for organization but isn’t always necessary. I’m still going to use it for things like “admin”… but for organizations (URLs and such) I do like to use routes because they’re more flexible.