E-Mail Client

Hello all,

Very new to ROR and am very fascinated by it. I am half-way through the
Agile book, and now would like to start learning using a different
example.

I am thinking for learning purposes, I would start with a very simple
web-based email client and then add functionality as I go along.

I know the following:
  * Need to read the local mbox file and present the From, Subject, and
date for each email in a list
  * Need to add functionality so that when I click, the email is
opened, with Reply, Forward, Delete and Back to Inbox links.

This is the bare minimum. Once I get there, I can start adding other
nicer functionality.

So, I ran "rail mailclient"..... and now am stuck :slight_smile: The MVC concept is
very new to me, and am really lost at which files I need to create and
where....

Any help is much appreciated. If there is anything that is not clear in
the above, please let me know and I will try to clarify.

Thanks,
Daly

That's great that you're trying to learn from a real world example, but
IMHO, I would start even simpler. Just create a hello world app and
play around with that until you understand MVC a bit more.

/app/controllers/first_controller.rb:

class FirstController < ActionController::Base
  def helloworld
    @my_output = "Hello World!"
  end
end

/app/views/first/helloworld.rhtml:

<h1>Message from controller: <%= @my_output %> </h1><br />

Start there, learn the core concepts, and your email application will
become much easier.

Thanks Chad.

I now need to:
  * Get number of emails on server (easy using pop or imap .mails.size
  * Parse the header to get Subject, Date, and From (I figured out the
code to do this)
  * Put that in a class along with the message contents (pretty simple)
  * Display all that info line by line (I have that ready, looks ugly,
but works :slight_smile:

I understand that ruby uses a MVC model, so I am supposed to put all
display logic in app/views, all code that receives actions from the
user in app/controllers, and the app/models directory would hold the
logic that brings this all together.

So the 4 steps above would probably need to placed in the app/models
directory and code in app/views will need to call it. If I want the
user to go to webserveraddress:3000/inbox, what would I need to call
the files I place in each subdirectory? Is there a command that takes
care of this for me?

Sorry for the very basic questions. Your help is appreciated.

The models are where you represent your information, such as a database.

The controllers are your logic. Keep reading the manual. The out-of-box
rails handling is like this:

www.yoursite.com/:controller/:action/:id

/app/controllers/inbox_controller.rb

def index
  # logic in here
end

would route like this:

:controller = inbox
:action = index

And accessed through URL like this:

www.yoursite.com/inbox/index

Or more simply, index action can be implied:

www.yoursite.com/inbox/

So this is what I have been busy doing. Looks pretty ugly, but it
works.

I will add reply, forward and delete buttons once I figure out how to
obtain the message body itself. You can check it out at
http://eldaly.com:3000/inbox

This is what I did so far:
rails mailclient
ruby script/generate controller Inbox index
create lib/email.rb (created an email class)
ruby script/generate controller View index

If I post the code here (and I would love to, to get feedback. I am
pretty sure there is some much better way of doing what I did and would
love to get some feedback) the post would be too long, is there an
alternative way, or is it OK to just go ahead an post the code?

Thanks.

You probably don't need a separate controller for view... just take
your index action from the view controller, put it in the inbox
controller, and rename it to the "view" action. Then you'll access the
email like this: http://eldaly.com:3000/inbox/view/2

Thank you very much for your responsiveness. That seems to be a design
decision, and I am not proficient in that yet. What decision would you
take to create a controller, or use an existing one? Also, where can I
post my code so that you and others can critique it?

Your time in answering all my questions is very much appreciated.

For what you've described, your entire app could consist of two controllers:
application controller and inbox controller.

The inbox controller is where most of your business logic will reside
(processing users requests, manipulating models, etc.)

A most excellent reply. Thank you very much. I agree that one is never
done reading. I skimmed through the parts I found most relevant to the
now, but know that I will need to go back when I will be stuck with
something that needs sessions for example.

Thank you all for you very helpful posts.

Thanks Ryan. I did just that and realized that the part I did not
continue with because I got tired of all the code had some very
important information.

Pointing this out re-enlightened me, LOL.

Time for the common "Message Body" question.

I see many posts about this, but not too many answers. I stumbled upon
Ruby Mail which seemed like a good solution, but getting the body of
the message seems to be broken. There have been others that have also
reported this. Doen't help when the code has not been updated in 2
years.

This is a great group. Thanks for all the help.

Regards,
Daly

So I fixed this by using tmail instead of rubymail. Works flawlessly. I
am a happy camper :slight_smile:

Actually you generally want one controller per model, to perform all the standard CRUD (Create, Read, Update, Delete) actions on one model.

Each controller should generally have 7 standard actions:

  • index (the list view)

  • show (view an existing item, no edit ability)

  • new (a form to create a new item)

  • create (the action the new form submits to, which actually creates the item - no view file)

  • edit (a form to update an existing item)

  • update (the action the edit form submits to, which actually updates the item - no view file)

  • destroy (the action which destroys an item and redirects to the list)

In your email app, you could have one Message model (doesn’t have to be a database model), and one Message controller. The seven standard actions above apply. It doesn’t need to be any more complex than that in most cases. (As in, not 100%, but close to 95).

If you try to generally follow this convention throughout your Rails apps, things will be easier, and you’ll get a REST compliant API for free (with ActiveResource).

For more info, see:

http://wiki.rubyonrails.org/rails/pages/CRUD

http://www.loudthinking.com/arc/000593.html

http://www.ryandaigle.com/articles/2006/06/30/whats-new-in-edge-rails-activeresource-is-here

One more thing, you should really play with the “scaffold_resource” generator to generate an example of the kind of code you should be writing.

It’s not meant to be a crutch or something that’s just going to generate your app for you, it’s a learning tool to use once or twice to demonstrate good patterns.

Here’s a good guide: http://www.softiesonrails.com/2006/9/25/quick-guide-to-the-new-scaffold_resource-generator

Thanks Scott. Very informative.

I proceeded to create to controllers inbox and message. Inbox just
displays a list of messages, and message can show, create, reply, reply
all, forward and delete. I think this falls well within what you were
saying above, as showing a message is different than showing a mailbox.
Also, I imagine the inbox controller will have other functionality such
as mark some messages for group operations (such as delete).

Thanks for the link.

Regards,
Ahmed