"Recipe organizer and sharing interface"

'Recipe organizer and sharing interface' screenshot
Use "Recipe organizer and sharing interface" Beta

Class: Ruby on Rails Spring 2009
Professor: Michael Schidlowsky
Date: 05/13/2009

= Contents =
Discussed in this readme:
* Usage
* ActiveRecord
* Layouts and Partials
* RESTful Resources and Routes
* Ajax and RJS
* Browser Compliance
* Other features
* Future
* Full disclosure of similar sites

= Usage =
Permissions are rather loose throughout the site, but some actions and features require a logged-in user. Create a user and log in to see full features of the app. I tried to leave a few users/ingredients/comments/recipes in the database so you can see the workings with out being overwhelmed. The idea for the app would be for users to build the site by adding recipes and ingredients wiki style.

= Active Record =
I have 5 relational tables: users, recipes, ingredients, portions, and comments. There are plenty of associations listed in detail below.

== Users ==
Have and belongs to many recipes (favorite recipes).
Have and belongs to many ingredients (pantry)
Have many comments
The user ActiveRecord is the end user's front end to the app. Many of features require a user to create an account and log in (pantry, favorite recipes, etc.)

== Recipes ==
Have and belongs to many users
Have many portions (and through which many ingredients)
Have many comments
The recipe contains information about a recipe and its ingredients stored in a portion ActiveRecord so that amount and units information can be unique accross recipes for the same ingredient and maintained with the recipe.

== Ingredients ==
Have and belongs to many users (pantry)
Have many portions (and through which many recipes)
The ingredient contains a name and notes field, with no information about amounts and units since this is an abstract record without any direct associations to recipes. Ingredients are maintained RESTfully and created on the fly so that they soak up any possible ingredients inputted by a user into a new recipe, pantry etc.

== Portions ==
Belongs to recipe
Belongs to ingredient
The portions essentially links a recipe to a global ingredient. This way ingredients can be global and unique but instances of the ingredients realized as portions with amounts and units may be tied to a recipe. Note that portions are not directly created RESTfully that is. There are created on the fly at a recipes inception.

== Comments ==
Belongs to recipe
Belongs to user
The comment here is very simple. Only a single user can "own" a comment and the comment can only apply to a single recipe. Note that comments are not directly created RESTfully that is. There are created on the fly at a recipe's info page, and only by the currently logged in user.


= Layouts and Partials =
I use a global layout and many partials. I use the partials to handle the forms for creating objects, but also I use partials in my AJAX updaters so that different updates can yield familiar and similar results.

= RESTful Resources and Routes =
Users, recipes, and ingredients are maintained as RESTful resources. Comments support updating, editting, destroying, viewing but not restful creation. Similarly with portions.

My routes were chosen to closely match RESTful routes in an ideal. So along with the RESTful routes of users, recipes and ingredients, there are routes like
user/login
user/logout
user/manage_ingredients/1 --> manage the pantry of ingredients for user 1
recipes/show_users/3 --> show the users who favor recipe 3
recipes/search ---> search the recipes
/ ---> since the search is the main purpose of the app this redirects to recipes/search
etc.

= AJAX and RJS =
I use AJAX to handle the asynchronous updates of the "available" and "mandatory" ingredients boxes on the search page, as well as the search itself. I also use similar AJAX code (though not close enough to merit sharing code) to update a user's pantry.

I used a lot of Ruby assisted javascript to do asynchronous in my app. There is some RJS, but I found it really difficult and cumbersome to pass parameters to RJS. Also, it did not feel correct to have so much logic in the RJS rather than the controller where logic belongs. So I stuck with ruby assisted AJAX for the most part. I did realize the power of RJS and included a toggle comments link on the recipes view.

= Browser Compliance =
I have tested this app on Mac Safari, Mac Firefox3 and Ubuntu Firefox2. Firefox doesn't support the text-shadow I use in the css, oh well.

= Other Features =
A user can search for recipes based on her pantry of ingredients. These and any other the user desires are listed as available ingredients and only recipes containing only available ingredients are returned from the search(filter). The user may also add mandatory ingredients, so that recipe must include a certain ingredient.

Ingredients are well displayed. By that I mean when listed in a recipe the pluralization matches the units and amount. When listed, created and used in a search they are maintained as singular that way lookups cane be done on the name without false negatives. Also this means fewer duplicates as banana and bananas refer to same singular banana ingredient.

= Future =
There is still potential to improve this app. Users could have multiple pantries. Users could comment on other users or on recipes. User avatars could be better protected. Declaring and editing the ingredients of a recipe is a little clunky with the text area parsing. This could be improved with more elaborated AJAX or forms. AJAX all over could be cleaned up as well as the look and feel, especially the very ruby-on-rails-template looking lists

I'm still debating whether the searching should be asynchronous. Since most users will be using a personal pantry, sharing a URL is not as important but saving a search url for reference might be and asynchronous does not provide that. On the other hand during a long search a user can refine her current list of ingredients.

= Full disclosure of similar sites =
Here is a list of URLs to sites performing a similar task to this app:
- http://www.ibiblio.org/oscookbook/downloads/OSCKBK.txt
- http://ezeating.net/
- http://www.recipematcher.com/
- http://cookingbynumbers.com/
- http://www.webtender.com/cgi-bin/imbselect
- http://www.supercook.com/
- http://recipesonrails.com/
- http://www.zacharyfox.com/blog/ruby-on-rails/password-hashing

Back to Programs