How to think in terms of MVC when designing a website


#1

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.


#2

Nebs P. 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: ;^)


#3

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.


#4

Nebs P. 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


#5

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?


#6

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


#7

Nebs P. 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.


Phlip


#8

2009/2/1 Phlip removed_email_address@domain.invalid

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


#9

Hi Nebs,

you may want to look at discussion @
http://blog.hasmanythrough.com/2008/4/2/simple-pages

Re: your question: no, you’d definitely don’t create “ContactInfo”
controller – probably a Pages controller like the Josh S.'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

On Jan 31, 11:24 pm, Nebs P. removed_email_address@domain.invalid


#10

Colin L. 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 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.


Phlip


#11

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!

On Feb 1, 9:05Â am, Nebs P. removed_email_address@domain.invalid


#12

Karel Minařík wrote:

you may want to look at discussion @
http://blog.hasmanythrough.com/2008/4/2/simple-pages

Re: your question: no, you’d definitely don’t create “ContactInfo”
controller – probably a Pages controller like the Josh S.'s (or
similar) solution.

Finally… thank you Karel and Patrick! That article is exactly what I
was looking for, a simple concrete answer to a simple question.

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).


#13

Nebs P. 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?