如何在模型索引页面上添加创建/编辑模型功能?

时间:2010-08-27 08:15:01

标签: ruby-on-rails model

好的,我有一个非常简单的模型:

ServiceType(id: integer, title: string, duration: integer, created_at: datetime, updated_at: datetime)

因为它如此简单,我应该有一个单独的页面来创建和更新这些类型的记录,这太荒谬了。我想要做的是在我的索引页面上有一个表单,我可以用它来创建新记录,如果我点击编辑链接,我希望表单加载该记录,以便表单兼作创建/更新表单

有没有人之前已经这样做了,或者有人知道某个博客文章显示了如何做到这一点?

编辑:使用Laheab下面发布的博客链接,我就是这样: 如果您使用的是Rails 3,Laheab的链接就是您想要的,但请注意!写这篇文章的人在他的代码中留下了大量明显的错误..寻找像*/ */而不是/* */这样的错误评论块,并寻找他使用jQuery但是放弃{{1}的时间}}

如果您使用的是Rails 2.3.x,我已将我的修改版本作为答案发布。

4 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

将“新服务类型”表单放在索引顶部很简单。它与“新”模板中的相同。

要编辑现有记录,您可能会考虑像in-place editing这样的东西,它曾经是rails core的一部分,但现在是一个插件。

答案 2 :(得分:1)

如果您运行的是Rails 2.3.x,则需要修改此人blog link中的内容。

这就是我做的创建/编辑/销毁(这还没有工作,它仍然因为某些原因将destroy.js.erb呈现为html)它可以工作:

制作rails app:

$ rails post_app
$ cd post_app
$ script/generate scaffold Post title:string content:text
$ rake db:migrate

现在添加/替换以下文件:

public / javascripts / application.js(参见Railscasts第136集http://railscasts.com/episodes/136-jquery):

// Setting up ajax for sending javascript requests
jQuery.ajaxSetup({
  'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
});

jQuery.fn.submitWithAjax = function() {
  this.submit(function() {
    $.post(this.action, $(this).serialize(), null, "script");
    return false;
  });
  return this;
};

jQuery.fn.getWithAjax = function() {
  this.click(function() {
    $.get(this.href, null, null, "script");
    return false;
  });
  return this;
};

jQuery.fn.postWithAjax = function() {
  this.click(function() {
    $.post(this.href, null, null, "script");
    return false;
  });
  return this;
};

应用程序/控制器/ posts_controller:

class PostsController < ApplicationController
  before_filter :load

  def load
    @posts = Post.all
    @post = Post.new
  end

  def index
  end

  def edit
    @post = Post.find(params[:id])
    respond_to do |format|
      format.all {render :file => "#{RAILS_ROOT}/public/404.html", :status => '404 Not Found'}
      format.js {render :layout => false}
    end
  end

  def create
    @post = Post.new(params[:post])

    if @post.save
      flash[:notice] = 'Post was successfully created.'
      @posts = Post.all
    end

    respond_to do |format|
      format.js {render :layout => false }
    end
  end

  def update
    @post = Post.find(params[:id])

    if @post.update_attributes(params[:post])
      flash[:notice] = 'Post was successfully updated.'
      @posts = Post.all
    end
    respond_to do |format|
      format.js {render :layout => false }
    end
  end

  def destroy
    @post = Post.find(params[:id])
    @post.destroy
    flash[:notice] = "Successfully destroyed post."
    @posts = Post.all
    respond_to do |format|
      format.js {render :layout => false }
    end
  end
end

应用程序/视图/布局/ posts.html.erb

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>Posts: <%= controller.action_name %></title>
  <%= stylesheet_link_tag 'scaffold' %>
  <%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js', 'application' %>
  <%= javascript_include_tag 'rails' %>
  <%= yield :head %>
</head>
<body>
  <div id="container">
    <div id="flash_notice" style="display: none; color: green"></div>
    <%= yield %>
  </div>
</body>
</html>

在app / views / posts下删除所有内容并添加以下文件:

index.html.erb:

<%- content_for :head do -%>
  <%= javascript_include_tag '/posts.js' %>
<% end %>
<h1>Listing posts</h1>
<%= render :partial => "form" %>
<div id="posts_list">
<%= render :partial => "posts" %>
</div>

index.js.erb的:

// Setting up the ajax requests for the forms/links.
$(document).ready(function() {
  $("#new_post").submitWithAjax();
  $("a.edit").each(function(){
    $(this).getWithAjax();
  });
  $("a.destroy").each(function(){
    $(this).postWithAjax();
  });
});

create.js.erb:

<% if @post.errors.any? -%>
  /*Hide the flash notice div*/
  $("#flash_notice").hide(300);

  /*Update the html of the div post_errors with the new one*/
  $("#post_errors").html("<%= escape_javascript(error_messages_for(@post))%>");

  /*Show the div post_errors*/
  $("#post_errors").show(300);
<% else -%>
  /*Hide the div post_errors*/
  $("#post_errors").hide(300);

  /*Update the html of the div flash_notice with the new one*/
  $("#flash_notice").html("<%= escape_javascript(flash[:notice])%>");

  /*Show the flash_notice div*/
  $("#flash_notice").show(300);

  /*Clear the entire form*/
  $(":input:not(input[type=submit])").val("");

  /*Replace the html of the div post_lists with the updated new one*/
  $("#posts_list").html("<%= escape_javascript( render(:partial => "posts") ) %>");
<% end -%>

destroy.js.erb:

$("#post_errors").hide(300);
$("#flash_notice").html("<%= escape_javascript(flash[:notice])%>");
$("#flash_notice").show(300);
$("#posts_list").html("<%= escape_javascript( render(:partial => "posts") ) %>");

_posts.erb:

<table>
  <tr>
    <th>Title</th>
    <th>Content</th>
  </tr>
  <% for post in @posts %>
    <tr>
      <td><%= post.title %></td>
      <td><%= post.content %></td>
      <td><%= link_to "Edit", edit_post_path(post), :class => "edit" %></td>
      <td><%= link_to "Destroy", post, :confirm => 'Are you sure?', :method => :delete, :class => 'destroy' %></td>
    </tr>
  <% end %>
</table>

edit.js.erb:

$("#new_post").html("<%= escape_javascript(render(:partial => "form"))%>");
$("#post_title").val('<%= escape_javascript(@post.title)%>');
$("#post_content").val('<%= escape_javascript(@post.content)%>');

_form.erb:

<% form_for @post do |f| %>
  <div id="post_errors" style="display:none"></div>
  <p>
    <%= f.label :title %><br/>
    <%= f.text_field :title %>
  </p>
  <p>
    <%= f.label :content %><br/>
    <%= f.text_area :content, :rows => 5 %>
  </p>
  <p><%= f.submit %></p>
<% end %>

update.js.erb:

<% if @post.errors.any? -%>
  $("#flash_notice").hide(300);
  $("#post_errors").html("<%= escape_javascript(error_messages_for(@post))%>");
  $("#post_errors").show(300);
<% else -%>
  $("#post_errors").hide(300);
  $("#flash_notice").html("<%= escape_javascript(flash[:notice])%>");
  $("#flash_notice").show(300);
  $(":input:not(input[type=submit])").val("");
  $("#posts_list").html("<%= escape_javascript( render(:partial => "posts") ) %>");
<% end -%>

答案 3 :(得分:-1)

首先,我将以RESTfull方式为此模型编写控制器,并使用partials编写适当的视图模板。然后我会在索引页面上渲染表单部分。可以使用AJAX来缓解事情 这个主题与组件等有关,而AFAIK Rails的组件方式是局部的,但让控制器发挥出色并不是一件容易的事。读:

  

第三,Rails的“控制器优先”   调度机制使   假设只有一个   页面上的“逻辑”和   休息是装饰。我的经验   做网络工作恰恰相反。   通常有3个或更多   页面上的逻辑片段(动态   菜单栏,搜索框,购物   购物车,实时聊天等)和拥有   选择哪一条逻辑   “控制器”不是最佳的   大卫波拉克

来源:http://wiki.github.com/dpp/liftweb/about-view-first

我很好奇uberpro Rails如何处理这些问题。