Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

adding multi-model editing using accepts_nested_attributes_for

  • Loading branch information...
commit c0557d510cb7b55753ce68e3b2d0563f42ad7bc3 1 parent 1fb85c2
@ryanb authored
View
13 app/helpers/application_helper.rb
@@ -1,3 +1,16 @@
# Methods added to this helper will be available to all templates in the application.
module ApplicationHelper
+ def add_task_link(name, f)
+ fields = new_child_fields(f, :tasks)
+ link_to_function(name, "insert_fields('tasks', '#{escape_javascript(fields)}')")
+ end
+
+ def new_child_fields(form_builder, method, options = {})
+ options[:object] ||= form_builder.object.class.reflect_on_association(method).klass.new
+ options[:partial] ||= method.to_s.singularize
+ options[:form_builder_local] ||= :f
+ form_builder.fields_for(method, options[:object], :child_index => 'NEW_RECORD') do |f|
+ render(:partial => options[:partial], :locals => { options[:form_builder_local] => f })
+ end
+ end
end
View
1  app/models/project.rb
@@ -1,4 +1,5 @@
class Project < ActiveRecord::Base
has_many :tasks
validates_presence_of :name
+ accepts_nested_attributes_for :tasks, :reject_if => lambda { |a| a.values.all?(&:blank?) }, :allow_destroy => true
end
View
1  app/views/layouts/application.html.erb
@@ -4,6 +4,7 @@
<head>
<title><%= h(yield(:title) || "Untitled") %></title>
<%= stylesheet_link_tag 'application' %>
+ <%= javascript_include_tag :defaults %>
<%= yield(:head) %>
</head>
<body>
View
10 app/views/projects/_form.html.erb
@@ -1,8 +1,16 @@
-<%= error_messages_for :project %>
<% form_for @project do |f| %>
+ <%= f.error_messages %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
+
+ <h3>Tasks</h3>
+ <div id="tasks">
+ <% f.fields_for :tasks do |task_form| %>
+ <%= render :partial => 'task', :locals => { :f => task_form } %>
+ <% end %>
+ </div>
+ <p><%= add_task_link "New Task", f %></p>
<p><%= f.submit "Submit" %></p>
<% end %>
View
6 app/views/projects/_task.html.erb
@@ -0,0 +1,6 @@
+<div class="field">
+ <%= f.label :name, "Task" %>
+ <%= f.text_field :name %>
+ <%= f.check_box :_delete %>
+ <%= f.label :_delete, "(remove)" %>
+</div>
View
6 public/javascripts/application.js
@@ -1,2 +1,8 @@
// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults
+function insert_fields(element_id, content) {
+ var new_id = new Date().getTime();
+ $(element_id).insert({
+ bottom: content.replace(/NEW_RECORD/g, new_id)
+ });
+}
View
7 public/stylesheets/application.css
@@ -68,15 +68,22 @@ body {
background-color: #c00;
color: #fff;
}
+
#errorExplanation p {
color: #333;
margin-bottom: 0;
padding: 8px;
}
+
#errorExplanation ul {
margin: 2px 24px;
}
+
#errorExplanation ul li {
font-size: 12px;
list-style: disc;
}
+
+.field {
+ margin: 8px 0;
+}
Please sign in to comment.
Something went wrong with that request. Please try again.