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