Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Mani Tadayon committed Sep 2, 2010
0 parents commit 0d86c12
Show file tree
Hide file tree
Showing 61 changed files with 10,219 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.bundle
db/*.sqlite3
log/*.log
tmp/**/*
17 changes: 17 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
source 'http://rubygems.org'

gem 'rails', '3.0.0'

gem "mongoid", "2.0.0.beta.17"
gem "bson_ext", "1.0.4"

gem 'formtastic', :git => "http://github.com/justinfrench/formtastic.git", :branch => "rails3"

gem 'haml', '>=3.0.13'

group :development do
gem 'ruby-debug'
gem 'mongrel' # easier for debugging
gem 'wirble'
gem 'awesome_print', :require => 'ap'
end
119 changes: 119 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
GIT
remote: http://github.com/justinfrench/formtastic.git
revision: e42d256ebe7fdbd3881665d94ce54cf061a9186f
branch: rails3
specs:
formtastic (1.1.0.beta)
actionpack (>= 2.3.0)
activesupport (>= 2.3.0)
i18n (>= 0.4.0)

GEM
remote: http://rubygems.org/
specs:
abstract (1.0.0)
actionmailer (3.0.0)
actionpack (= 3.0.0)
mail (~> 2.2.5)
actionpack (3.0.0)
activemodel (= 3.0.0)
activesupport (= 3.0.0)
builder (~> 2.1.2)
erubis (~> 2.6.6)
i18n (~> 0.4.1)
rack (~> 1.2.1)
rack-mount (~> 0.6.12)
rack-test (~> 0.5.4)
tzinfo (~> 0.3.23)
activemodel (3.0.0)
activesupport (= 3.0.0)
builder (~> 2.1.2)
i18n (~> 0.4.1)
activerecord (3.0.0)
activemodel (= 3.0.0)
activesupport (= 3.0.0)
arel (~> 1.0.0)
tzinfo (~> 0.3.23)
activeresource (3.0.0)
activemodel (= 3.0.0)
activesupport (= 3.0.0)
activesupport (3.0.0)
arel (1.0.1)
activesupport (~> 3.0.0)
awesome_print (0.2.1)
bson (1.0.4)
bson_ext (1.0.4)
builder (2.1.2)
cgi_multipart_eof_fix (2.5.0)
columnize (0.3.1)
daemons (1.1.0)
erubis (2.6.6)
abstract (>= 1.0.0)
fastthread (1.0.7)
gem_plugin (0.2.3)
haml (3.0.18)
i18n (0.4.1)
linecache (0.43)
mail (2.2.5)
activesupport (>= 2.3.6)
mime-types
treetop (>= 1.4.5)
mime-types (1.16)
mongo (1.0.7)
bson (>= 1.0.4)
mongoid (2.0.0.beta.17)
activemodel (~> 3.0.0)
bson (= 1.0.4)
mongo (= 1.0.7)
tzinfo (~> 0.3.22)
will_paginate (~> 3.0.pre)
mongrel (1.1.5)
cgi_multipart_eof_fix (>= 2.4)
daemons (>= 1.0.3)
fastthread (>= 1.0.1)
gem_plugin (>= 0.2.3)
polyglot (0.3.1)
rack (1.2.1)
rack-mount (0.6.13)
rack (>= 1.0.0)
rack-test (0.5.4)
rack (>= 1.0)
rails (3.0.0)
actionmailer (= 3.0.0)
actionpack (= 3.0.0)
activerecord (= 3.0.0)
activeresource (= 3.0.0)
activesupport (= 3.0.0)
bundler (~> 1.0.0)
railties (= 3.0.0)
railties (3.0.0)
actionpack (= 3.0.0)
activesupport (= 3.0.0)
rake (>= 0.8.4)
thor (~> 0.14.0)
rake (0.8.7)
ruby-debug (0.10.3)
columnize (>= 0.1)
ruby-debug-base (~> 0.10.3.0)
ruby-debug-base (0.10.3)
linecache (>= 0.3)
thor (0.14.0)
treetop (1.4.8)
polyglot (>= 0.3.1)
tzinfo (0.3.23)
will_paginate (3.0.pre2)
wirble (0.1.3)

PLATFORMS
ruby

DEPENDENCIES
awesome_print
bson_ext (= 1.0.4)
formtastic!
haml (>= 3.0.13)
mongoid (= 2.0.0.beta.17)
mongrel
rails (= 3.0.0)
ruby-debug
wirble
95 changes: 95 additions & 0 deletions README.textile
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
*** TODO ***
* use :reject_if in accepts_nested_attributes_for
* get rid of blank entries in controller
* add _destroy method to model so :allow_destroy works
* when using update_attributes on an embedded document, make sure to do parent_model_.update_attributes and NOT embedded_model.update_attributes


h2. Mongoid

Here are some tips for using Formtastic with Mongoid on Rails 3. It's important to use Rails 3 because both Formtastic and Mongoid use Rails 3's ActiveModel for important things like validations.

The following was implemented using Formtastic 1.1.0.beta, Mongoid 2.0.0.beta.17 and Rails 3.0.0.

I've had success using Mongoid with Formtastic for some pretty intricate nested forms. It took me a while to figure out how to handle these kind of forms even with ActiveRecord, so I'd say using Mongoid is not a problem, although there are some gotchas. The following info is based on my limited experience using Mongoid with Formtastic and I'm sure there is plenty of room for improvement, so please add/edit this wiki if you have suggestions!

When using Mongoid with Formtastic, simple forms work just like on ActiveRecord models. When you have nested forms for relationships and embedded documents, there are some complications because of the variety of ways to implement relationships in Mongoid.

h3. Formtastic form for Mongoid `references_many`
So let's say you have the following Mongoid models with a many-to-many relationship:

<pre>
class User
include Mongoid::Document

field :name
field :email
field :active, :type => Boolean

# :stored_as => :array is important to getting Formtastic to work
references_many :user_types, :stored_as => :array, :inverse_of => :users
end
</pre>

<pre>
class UserType
include Mongoid::Document

field :name

references_many :users, :stored_as => :array, :inverse_of => :user_types
end
</pre>

Then your form for a new user would look something like:
<pre>
= semantic_form_for(@user) do |form|
%fieldset
%legend
Add a new user

= form.inputs do
= form.input :name
= form.input :email

-# must specify `:as => boolean`, Formtastic doesn't detect the field type automatically
= form.input :active, :as => :boolean
= form.input :user_types, :as => :check_boxes, :collection => UserType.all.map{|ut| [ut.name,ut._id]}
</pre>

h3. Formtastic form for Mongoid embedded documents

This gets a little ugly. But I previously had this formtastic form implemented with ActiveRecord, and it was even more complex!

Let's say you have the following models:

<pre>
class User
include Mongoid::Document

field :name
field :email
field :active, :type => Boolean

embeds_many :messages
end
</pre>

<pre>
class Message
include Mongoid::Document

field :title
field :content
embedded_in :user, :inverse_of => :messages
end
</pre>

Then your formtastic form would look something like:
<pre>

</pre>

2 important things to keep in mind:
* Mongoid allows for very flexible relationships and embeds. When using ActiveRecord with Formtastic there is usually a 'right way' of handling forms. With Mongoid you have to think things through and see how your documents are being stored (the mongo shell is your friend here).
* Field types are not picked up automatically, so you have to specify if you have a Boolean field type
7 changes: 7 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.

require File.expand_path('../config/application', __FILE__)
require 'rake'

FormtasticMongoidWiki::Application.load_tasks
3 changes: 3 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class ApplicationController < ActionController::Base
protect_from_forgery
end
31 changes: 31 additions & 0 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
class UsersController < ApplicationController
def index
@users = User.all
end

def new
@user = User.new
end

def create
debugger

params[:user][:user_type_ids].reject!{|ut_id| ut_id.blank?}

@user = User.new(params[:user])

respond_to do |format|
if @user.save
flash[:notice] = 'User was successfully created.'
redirect_to @user
else
flash[:alert] = 'User was NOT created.'
format.html { render :action => "new" }
end
end
end

def show
@user = User.criteria.id([params[:id]])
end
end
2 changes: 2 additions & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module ApplicationHelper
end
2 changes: 2 additions & 0 deletions app/helpers/users_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module UsersHelper
end
7 changes: 7 additions & 0 deletions app/models/message.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Message
include Mongoid::Document

field :title
field :content
embedded_in :user, :inverse_of => :messages
end
17 changes: 17 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class User
include Mongoid::Document

field :name
field :email
field :active, :type => Boolean

# :stored_as => :array is important to getting Formtastic to work
references_many :user_types, :stored_as => :array, :inverse_of => :users do
def to_s
@target.map(&:name).join(', ')
end
end
embeds_many :messages

accepts_nested_attributes_for :messages, :allow_destroy => true, :reject_if => proc { |attributes| attributes['name'].blank? and attributes['_destroy'].blank? }
end
9 changes: 9 additions & 0 deletions app/models/user_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class UserType
include Mongoid::Document

field :name

references_many :users, :stored_as => :array, :inverse_of => :user_types

validates :name, :presence => true, :uniqueness => true
end
15 changes: 15 additions & 0 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<title>FormtasticMongoidWiki</title>
<%= stylesheet_link_tag :all %>
<%= formtastic_stylesheet_link_tag %>
<%= javascript_include_tag :defaults %>
<%= csrf_meta_tag %>
</head>
<body>

<%= yield %>

</body>
</html>
Empty file added app/views/users/edit.html.haml
Empty file.
9 changes: 9 additions & 0 deletions app/views/users/index.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
- @users.each do |user|
%ul
- %w( name email user_types ).each do |field|
%li
%strong
= field.titleize + ' : '
= user.send(field)

%hr
14 changes: 14 additions & 0 deletions app/views/users/new.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
= semantic_form_for(@user) do |form|
%fieldset
%legend
Add a new user

= form.inputs do
= form.input :name
= form.input :email

-# must specify `:as => boolean`, Formtastic doesn't detect the field type automatically
= form.input :active, :as => :boolean
= form.input :user_type_ids, :as => :check_boxes, :collection => UserType.all.map{|ut| [ut.name,ut._id]}

= form.buttons
5 changes: 5 additions & 0 deletions app/views/users/show.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
%ul
- %w( name email user_types ).each do |field|
%li
%strong= field.titleize
%p= @user.send(field)
4 changes: 4 additions & 0 deletions config.ru
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# This file is used by Rack-based servers to start the application.

require ::File.expand_path('../config/environment', __FILE__)
run FormtasticMongoidWiki::Application
Loading

0 comments on commit 0d86c12

Please sign in to comment.