如何使用索引操作&索引模板? [英] How to get the output of a nested form to stay in its exact original order, despite permutations, using the index action & index template?

查看:98
本文介绍了如何使用索引操作&索引模板?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用嵌套表单发布Urls和文本。通过javascript,我允许这两个字段的任何排列,例如Url1 Text1 Text2 Url2或Url1 Text1 Url2 Text2等

I am using a nested form to post Urls and Texts. Via javascript, I am allowing any permutation of these two fields e.g. Url1 Text1 Text2 Url2 or Url1 Text1 Url2 Text2 etc

提交表单并重定向到index.html.view之后,我然后尝试保留我决定在表单中使用的任何排列的原始顺序,即是否决定发布Text1 Url1 Url2 Text2 Url3我需要完全相同的安排才能在浏览器中显示。

After submitting the form and redirecting to the index.html.view, I am then trying to keep the original order of whatever permutation I decide to use in the form i.e. if I decided to post Text1 Url1 Url2 Text2 Url3 I need that exact same arrangement to display in the browser.

邮政表格代码

Post Model

Post Model

 class Post < ActiveRecord::Base
   has_many :texts
   has_many :urls    
   accepts_nested_attributes_for :texts, :urls 
 end

文本模型

 class Text < ActiveRecord::Base
  belongs_to :post 
 end

Url Model

Url Model

 class Url < ActiveRecord::Base
  belongs_to :post
 end

Schema

 ActiveRecord::Schema.define(version: 20160215123916) do

 create_table "posts", force: :cascade do |t|
 t.datetime "created_at", null: false
 t.datetime "updated_at", null: false
  end

 create_table "texts", force: :cascade do |t|
  t.text     "textattr"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.integer  "post_id"
 end

 add_index "texts", ["post_id"], name: "index_texts_on_post_id"

 create_table "urls", force: :cascade do |t|
  t.string   "urlattr"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.integer  "post_id"
 end

 add_index "urls", ["post_id"], name: "index_urls_on_post_id"

end

Posts Controller

Posts Controller

  class PostsController < ApplicationController

  def index
    @posts = Post.includes(:texts, :urls).all.order(created_at: :desc)
  end

  def new
    @post = Post.new 
   end 

  def create
   @post = Post.new(post_params) 
    if @post.save 
      redirect_to '/posts'
    else 
      render 'new'
    end 
  end

   private 
    def post_params 
        params.require(:post).permit(:texts_attributes => [:textattr], :urls_attributes => [:urlattr])
    end 
 end

Index.html.erb(尝试失败)

Index.html.erb (Unsuccessful Attempt)

<% @posts.each do |post| %> 

<% post.texts.each do |text|%>
 <%= text.textattr %> <br> 
<% end %>

<% post.urls.each do |url|%>
 <%= url.urlattr %> <br> 
<% end %> 

<% end %> 

Index.html.erb(尝试失败)

Index.html.erb (Unsuccessful Attempt)

   <% @posts.each do |post| %> 

    <% [post.texts, post.urls].flatten.sort_by { |c| [c.created_at] }.each do |content| %>
      <% if content.class.name == "Text" %>
        <%= content.textattr %> 
      <% elsif content.is_a? Url %>
         <%= content.urlattr %> 
      <% end %> 
    <% end %>

  <% end %>  


推荐答案

Richard说,您需要添加订单列(或排名-调用列 order 会引起与生成的SQL的混淆。

As Richard says, you need to add an order column (or position - calling the column order can cause confusion with the generated SQL).

我认为主要问题是您的咖啡代码。您需要为添加的每一行生成一个隐藏的输入,并对添加的行使用单个 current_index 计数器:

I think the main issue is your coffeescript code. You need to generate a hidden input with each row you add, and use a single current_index counter for row you add:

current_index = 0

addText = ->
 html = """
 <br>
  <textarea name="post[things_attributes][#{current_index}][text]" id="post_things_attributes_#{current_index}_text"></textarea>
  <input type="hidden" name="post[things_attributes][#{current_index}][order]" id="post_things_attributes_#{current_index}_order" value="#{current_index}" />
 """

 $("#new_post input[type='submit']").before(html)
 current_index += 1

addUrl = ->
 html = """
 <br>
  <input type="url" name="post[things_attributes][#{current_index}][url]" id="post_things_attributes_#{current_index}_url">
  <input type="hidden" name="post[things_attributes][#{current_index}][order]" id="post_things_attributes_#{current_index}_order" value="#{current_index}" />
 """

 $("#new_post input[type='submit']").before(html)
 current_index += 1

在您的 index.html.erb ,请按 order 列对 Things 进行排序:

In your index.html.erb, order the Things by the order column:

<% @posts.each do |post| %>
  <% post.things.order(:order).each do |thing| %>
    <br>
    <%= thing.try(:text) %>
    <%= thing.try(:url) %>
  <% end %>

  <br>
<% end %>






还值得注意的是,这种动态嵌套表单模式茧宝石的处理非常好。建议您在项目中使用它。


It's also worth noting that this dynamic nested form pattern is very well-handled by the cocoon gem. I'd recommend taking a look and using that in your project.

这篇关于如何使用索引操作&amp;索引模板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆