原创作者: hideto   阅读:1239次   评论:0条   更新时间:2011-05-26    
前两次学习了动态添加和删除project的多个tasks,这次来看看如何编辑project

其他页面不变,但是_task.rhtml改了:
<!-- projects/edit.rhtml -->
<% form_for :project, :url => project_path(@project), :html => { :method => 'put' } do |f| %>
  <%= render :partial => 'fields', :locals => { :f => f } %>
  <p><%= submit_tag "Update Project" %></p>
<% end %>

<!-- projects/new.rhtml -->
<% form_for :project, :url => projects_path do |f| %>
  <%= render :partial => 'fields', :locals => { :f => f } %>
  <p><%= submit_tag "Create Project" %></p>
<% end %>

<!-- projects/_fields.rhtml -->
<p>
  Name: <%= f.text_field :name %>
</p>
<div id="tasks">
  <%= render :partial => 'task', :collection => @project.tasks %>
</div>
<%= add_task_link "Add a task" %>

<!-- projects/_task.rhtml -->
<div class="task">
  <% fields_for "project[task_attributes][]", task do |f| %>
    <p>
      Task: <%= f.text_field :name, :index => nil %>
      <% if task.new_record? %>
        <%= link_to_function "remove", "$(this).up('.task').remove()" %>
      <% else %>
        <%= link_to_function "remove", "mark_for_destroy(this)" %>
        <%= f.hidden_field :id, :index => nil %>
        <%= f.hidden_field :should_destroy, :index => nil, :class => 'should_destroy' %>
      <% end %>
    </p>
  <% end %>
</div>

在_task.rhtml页面中判断task是不是new_record,如果不是new_record则调用自定义的mark_for_destroy方法:
// application.js
function mark_for_destroy(element) {
  $(element).next('.should_destroy').value = 1;
  $(element).up('.task').hide();
}

在Model层添加和修改一些方法:


# models/project.rb
class Project < ActiveRecord::Base
  has_many :tasks
  after_update :save_tasks

  def task_attributes=(task_attributes)
    task_attributes.each do |attributes|
      if attributes[:id].blank?
        tasks.build(attributes)
      else
        task = tasks.detect { |t| t.id == attributes[:id].to_i }
        task.attributes = attributes
      end
    end
  end

  def save_tasks
    tasks.each do |t|
      if t.should_destroy?
        t.destroy
      else
        t.save(false)
      end
    end
  end
end

# models/task.rb
class Task < ActiveRecord::Base
  belongs_to :project
  attr_accessor :should_destroy

  def should_destroy?
    should_destroy.to_i == 1
  end
end

Controller则还是保持不变:
# projects_controller.rb
def edit
  @project = Project.find(params[:id])
end

def update
  @project = Project.find(params[:id])
  if @project.update_attributes(params[:project])
    flash[:notice] = "Successfully updated project."
    redirect_to projects_path
  else
    render :action => 'edit'
  end
end
评论 共 0 条 请登录后发表评论

发表评论

您还没有登录,请您登录后再发表评论

文章信息

Global site tag (gtag.js) - Google Analytics