Как добавить функцию создания / редактирования моделей на странице индекса модели? - PullRequest
2 голосов
/ 27 августа 2010

Хорошо, у меня есть очень простая модель:

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

Поскольку это так просто, смешно, что у меня есть отдельная страница для создания и обновления этих типов записей. То, что я хотел бы сделать, это иметь форму на моей странице индекса, которую я могу использовать для создания новых записей, и если я нажму на ссылку редактирования, я бы хотел, чтобы форма загружала эту запись, чтобы форма удваивалась как форма создания / обновления .

Кто-нибудь уже делал это раньше или кто-нибудь знает где-нибудь статью в блоге, где показано, как это сделать?

РЕДАКТИРОВАТЬ: Используя ссылку на блог, размещенную ниже Laheab, я нахожусь на этом этапе: Если вы используете Rails 3, ссылка Laheab - это то, что вы хотите, но БУДЬТЕ ПРЕДУПРЕЖДЕНЫ !! Парень, который написал это, оставил кучу очевидных ошибок в своем коде ... ищите блоки плохих комментариев, такие как */ */ вместо /* */ и ищите моменты, когда он использует jQuery, но пропускает $.

ЕСЛИ вы используете Rails 2.3.x, я опубликовал свою модифицированную версию в качестве ответа.

Ответы [ 4 ]

2 голосов
/ 28 августа 2010
1 голос
/ 29 августа 2010

Если вы работаете с Rails 2.3.x, вам нужно изменить то, что парень делает в этой ссылке в блоге .

Это то, что я сделал, чтобы создать / редактировать / уничтожить (это еще не работает, он все еще отображает destroy.js.erb как html по какой-то причине) это работает:

приложение make rails:

$ 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;
};

app / controllers / 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

app /views / layouts / 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 -%>
1 голос
/ 27 августа 2010

Просто поместить форму «новый тип сервиса» в верхней части индекса.Это так же, как если бы это было в «новом» шаблоне.

Чтобы редактировать существующие записи, вы можете рассмотреть что-то вроде редактирования на месте , который раньше был частью рельсовядро, но теперь это плагин.

0 голосов
/ 27 августа 2010

Прежде всего, я бы написал контроллер для этой модели в режиме RESTfull и написал бы соответствующие шаблоны представления, используя партиалы.Затем я бы отобразил партиалы формы на странице индекса. Вероятно, использование AJAX облегчит задачу.
Эта тема связана с компонентами и т. Д., И AFAIK путь к компонентам в Rails - это партиалы, но заставить контроллеры играть хорошо не легкозадача.Читайте:

В-третьих, механизм диспетчеризации Rails «сначала контролирует» предполагает, что на странице есть только одна часть «логики», а остальное - украшение.Мой опыт работы в сети - прямо противоположный.Обычно на странице имеется 3 или более элементов логики (динамические строки меню, поля поиска, корзина покупок, чат в реальном времени и т. Д.), И необходимость выбирать, какой элемент логики делает «контроллер», является менее чем оптимальной.
Дэвид Поллак

Источник: http://wiki.github.com/dpp/liftweb/about-view-first

Мне интересно, как разработчики uberpro Rails справляются с этими проблемами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...