How to think in terms of MVC when designing a website.

I'm fairly new to rails but I've read a book, many tutorials and watched video lectures so I'm starting to get a hang of how it works.

I've now decided to jump in and create a rails app from scratch. I'm a little confused when it comes to going from concept to implementation using MVC. I understand when to use models, pretty much whenever I have an object that I want to store in a database or resource. What I'm not sure about is when to create a controller. For basic tasks like creating/editing users, sessions or objects it makes sense. But what about other pages in my website that are not necessarily dealing with CRUD on objects?

For example if I have a website with multiple pages like "contact us" or "help" which don't deal with dynamic content but rather display just a static page of information. Is it common practice to create a controller for every page in my website (and use its 'show' method), even if they're static and "hard coded"?

I would like to use a single application.html.erb layout for the entire website, so adding simple pages like "contact us" are confusing to me because I don't know if I should just create an html file somewhere or have rails generate a view via a "dummy" controller so that it can use the layout?

Another question I have is regarding to the index.html page in the public folder. Is there a way to utilize the application.html.erb layout for this page as well? If not, how can I create a "home" page that sort of fits in with the rest of the application.

Thanks for any help.

Nebs Petrovic wrote:

I've now decided to jump in and create a rails app from scratch. I'm a little confused when it comes to going from concept to implementation using MVC. I understand when to use models, pretty much whenever I have an object that I want to store in a database or resource. What I'm not sure about is when to create a controller. For basic tasks like creating/editing users, sessions or objects it makes sense. But what about other pages in my website that are not necessarily dealing with CRUD on objects?

Always remember that once you carve your design into stone, you can never change it. So make sure you get the design right before you start carving!

(This is a winkie: ;^)

Always remember that once you carve your design into stone, you can never change it. So make sure you get the design right before you start carving!

(This is a winkie: ;^)

That's why I'm posting this thread.

Nebs Petrovic wrote:

Always remember that once you carve your design into stone, you can never change it. So make sure you get the design right before you start carving!

(This is a winkie: ;^)

That's why I'm posting this thread.

Then you didn't get my winkie.

Software is soft. Write whatever works, with unit tests, and then refactor it (while running the tests), until the design is DRY. (Don't Repeat Yourself.)

Because a clean design typically falls into three layers, you don't need to guess, before coding, what the design should be. Write what you need, based on the behaviors you add to each page. Refactor towards DRY, and you will have the right things in the right layers, spontaneously.

Wall-to-wall unit tests are more important than a good design. If I had to select between working on two programs, one with an awesome design but no tests, the other with a bad design but wall-to-wall tests, I would choose the latter. But it's the designs without tests that get carved in stone.

Phlip wrote:

Because a clean design typically falls into three layers, you don't need to guess, before coding, what the design should be. Write what you need, based on the behaviors you add to each page. Refactor towards DRY, and you will have the right things in the right layers, spontaneously.

Ok I understand what you're saying. I'm not just trying to design everything before I get my feet wet, I've already started and I know how to implement features when I can clearly see them fit into an MVC "model".

I just hit a roadblock (which is why I'm here) because I wanted to accomplish a simple task like "ok, I have a "contact us" link, now I want it to point to a page that displays contact information". Now my question is, do I create a controller called ContactInfo and then use its show method to display this page? Or should this page be a method call of some other controller? Or none of the above?

Hypothetical (and unrealistic) situation: Just think of a completly static website with no control logic, just links to other static pages. How would you do this with rails? Do you create a controller called "Website" and have a method for each page? Or do you create a controller for each page and use their show methods to display the views? Or do you not even create controllers?

Ok now stepping out of this hypothetical bubble. Let's say now my website is filled with static pages but has the ability to login/logout users (dynamic aspect). Now the user authentication I can deal with in rails. My problem is how to handle the rest of that static stuff (the other pages) while still being able to use the application.html.erb as a layout for every page (including the static ones). Do you see what I mean?

Nebs Petrovic wrote:

Ok I understand what you're saying. I'm not just trying to design everything before I get my feet wet, I've already started and I know how to implement features when I can clearly see them fit into an MVC "model".

(BTW "Ok" is spelled "Okay" - it's a real word. OK is an historical backronym.)

The amount of books you seem to have read to get here indicates you like researching before doing!

I just hit a roadblock (which is why I'm here) because I wanted to accomplish a simple task like "ok, I have a "contact us" link, now I want it to point to a page that displays contact information". Now my question is, do I create a controller called ContactInfo and then use its show method to display this page? Or should this page be a method call of some other controller? Or none of the above?

Do the simplest thing that could possibly work. Just keep telling yourself "You Aren't Gonna Need It." YAGNI.

contact_us.html is just names and (shrouded) addresses, so throw it into public/

Its link is now link_to 'Contact Us', '/contact_us.html'. Put that into layout.html.erb, and you are done; all pages have it.

Hypothetical (and unrealistic) situation: Just think of a completly static website with no control logic, just links to other static pages. How would you do this with rails? Do you create a controller called "Website" and have a method for each page? Or do you create a controller for each page and use their show methods to display the views? Or do you not even create controllers?

The other good thing about YAGNI is it usually errs on the side of performance. Counterexamples abound, but in this case giving static HTML pages to your web server, without any Ruby code between them and your clients, is the most efficient technique!

Ok now stepping out of this hypothetical bubble. Let's say now my website is filled with static pages but has the ability to login/logout users (dynamic aspect). Now the user authentication I can deal with in rails. My problem is how to handle the rest of that static stuff (the other pages) while still being able to use the application.html.erb as a layout for every page (including the static ones). Do you see what I mean?

Yes. You are my "onsite customer", and we just wrote a static website in HTML. Now you want logic, so I refactor it.

Add the Salted Authentication plugin. Write tests that show some pages require users. (The plugin comes with the login_as test helper.)

Use tidy -i -asxhtml --wrap 130 -m file.html to convert the HTML to XHTML (so it's compliant & testable). Fix every error and warning. Move the files from public to app/views/my_controller/

You only need one controller so far. Use routes.rb

Pass all the tests, and write tests with assert_generates which check the routes are correct.

Now tell me the next feature and I will sketch out the migration path for you! The point is to use tests to ensure that each change - from too simple to less simple - is safe and elegant, not a bunch of hacking and thrashing.

I think it is possible that you might be missing the OP’s point. (Or, equally possible, I read a completely different question in the original post.) I think that Nebs would like to create a website with both static and dynamic pages that has a consistent look and feel. It sounds like (s)he would like to adhere to the DRY principle and not have to duplicate things between the application.html.erb file and the static content files. How typical this is I have no idea (being a newbie myself), but that’s what I read into the original question. One solution would be to write controllers that serve up the static content as if it were dynamic – a funny sort of dynamic page in which nothing ever changes. I think that what (s)he is asking is, “Is this the right/best thing to do?” and “What do other folks do in this situation?”

Unfortunately, I don’t have any good answers to those questions. What little I know of HTML/CSS makes me know that it’s possible to do an amazing amount changing the look and feel of a webstite using CSS (see http://www.csszengarden.com/). What little I know of RoR makes me know that when you involve controllers in serving up content, it slows things down. Since the developers of RoR are aware of this, they have added several different mechanisms to cache content so that things are slowed down as minimally as possible.

Perhaps the OP doesn’t care about speed, in which case the idea of using application.html.erb and CSS to define the common look & feel of the site, along with a “serve up the static content identified by the rest of the URL” controller will work fine. Perhaps that will be too slow, but by enabling caching of the pages served by that controller, the speed will be sufficient. Perhaps I am totally off base on what the original poster was asking. Regardless, it’s late and I’m going to bed now :slight_smile:

–wpd

Do the simplest thing that could possibly work. Just keep telling yourself "You

Aren’t Gonna Need It." YAGNI.

contact_us.html is just names and (shrouded) addresses, so throw it into public/

Its link is now link_to ‘Contact Us’, ‘/contact_us.html’. Put that into

layout.html.erb, and you are done; all pages have it.

Does layout.html.erb apply layout to pages in public/ ? Where does the file live?

Colin Law wrote:

    Its link is now link_to 'Contact Us', '/contact_us.html'. Put that into     layout.html.erb, and you are done; all pages have it.

Does layout.html.erb apply layout to pages in public/ ? Where does the file live?

layout.html.erb cannot wrap things in public/. The web server sees public/ first and, if it can serve a request, the server itself ships the file out.

I meant that View things can write links, like <a href='/contact_us.html'> that go to public/

If you want a common layout around static HTML, you need the next step in complexity - move contact_us.html into the view.

Hi Nebs,

you may want to look at discussion @ has_many :through - simple pages

Re: your question: no, you'd definitely don't create "ContactInfo" controller -- probably a Pages controller like the Josh Susser's (or similar) solution.

(When you want to just place a full static HTML file (like "Terms of Service") into otherwise dynamic application, you may just drop some terms_of_service.html file into `public`.)

--karmi

I wrestled with the same question of where to put static content, until I saw the excellent railscast on semi static pages. Check it out www.railscasts.com/episodes/117

The approach I use now is to great a staticpagescontroller in all my projects. You get the benefit of layouts, and can also use caching for performance boost.

Good luck!

Nebs Petrovic wrote:

Phlip, you completely missed the question. Also in the future try to leave condescending remarks and sarcasm to yourself when trying to help someone (especially over the internet).

Sorry, man. In terms of the dichotomy between "give a fish, teach how to fish"... I have probably been watching too much "House", huh?