单个页面中同一模型的多个表单

Tom*_*man 7 ruby forms ruby-on-rails

在我的说唱歌词解释网站的首页,有一个地方,用户可以尝试解释一个具有挑战性的线:

alt text http://dl.dropbox.com/u/2792776/screenshots/2010-02-06_1620.png

这是我用来生成这个的部分:

<div class="stand_alone annotation" data-id="<%= annotation.id %>">
  <%= song_link(annotation.song, :class => :title) %>

  <span class="needs_exegesis"><%= annotation.referent.strip.gsub(/\n/, "\n <br />") %></span>

  <% form_for Feedback.new(:annotation_id => annotation.id, :created_by_id => current_user.try(:id), :email_address => current_user.try(:email)), :url => feedback_index_path, :live_validations => true do |f| %>
    <%= f.hidden_field :annotation_id %>
    <%= f.hidden_field :created_by_id %>
    <p style="margin-top: 1em">
        <%= f.text_area :body, :rows => 4, :style => 'width:96%', :example_text => "Enter your explanation" %>
    </p>
    <p>
      <% if current_user %>
        <%= f.hidden_field :email_address %>
      <% else %>
        <%= f.text_field :email_address, :example_text => "Your email address" %>
      <% end %>
      <%= f.submit "Submit", :class => :button, :style => 'margin-left: .1em;' %>
    </p>
  <% end %>
</div>
Run Code Online (Sandbox Code Playgroud)

但是,将多个这些放在一个页面上是有问题的,因为Rails会自动为每个表单提供一个ID new_feedback,并且每个字段都有一个ID feedback_body(导致名称冲突)

显然我可以添加类似于:id => ''表单及其所有字段的内容,但这似乎有点重复.最好的方法是什么?

Dan*_*ski 11

如果您不想更改输入名称或模型结构,可以使用该id选项使表单ID唯一,并namespace选择使输入ID唯一:

<%= form_for Feedback.new(...), 
    id: "annotation_#{annotation.id}_feedback"
    namespace: "annotation_#{annotation.id}" do |f| %>
Run Code Online (Sandbox Code Playgroud)

这样我们的表单ID是唯一的,即annotation_2_feedback,这也将添加前缀,例如annotation_2_,通过创建的每个输入f.


Anu*_*rag 6

您是否考虑过rails模型的nested_attributes?new您可以使用多个edit注释表单,其中每个注释包含新反馈的字段,而不是具有多个反馈表单,其中每个表单都与注释相关联.生成的表单的id将包括注释id,例如edit_annotation_16.

注释模型与其反馈有关系,也会接受它们的嵌套属性.

class Annotation < ActiveRecord::Base
  has_many :feedbacks
  accepts_nested_attributes_for :feedbacks
end

class Feedback < ActiveRecord::Base
  belongs_to :annotation
end
Run Code Online (Sandbox Code Playgroud)

然后,您可以根据需要添加任意数量的表单,每个表单对应一个注释.例如,这是我尝试过的:

<% form_for @a do |form| %>
    Lyrics: <br />
    <%= form.text_field :lyrics %><br />
    <% form.fields_for :feedbacks do |feedback| %>
        Feedback: <br/>
        <%= feedback.text_field :response %><br />
    <% end %>
    <%= form.submit "Submit" %>
<% end %>

<% form_for @b do |form| %>
    Lyrics: <br />
    <%= form.text_field :lyrics %><br />
    <% form.fields_for :feedbacks do |feedback| %>
        Feedback: <br/>
        <%= feedback.text_field :response %><br />
    <% end %>
    <%= form.submit "Submit" %>
<% end %>
Run Code Online (Sandbox Code Playgroud)

以上编辑视图的快速和脏控制器:

class AnnotationsController < ApplicationController
  def edit
    @a = Annotation.find(1)
    @a.feedbacks.build
    @b = Annotation.find(2)
    @b.feedbacks.build
  end

  def update
    @annotation = Annotation.find(params[:id])
    @annotation.update_attributes(params[:annotation])
    @annotation.save!
    render :index
  end
end
Run Code Online (Sandbox Code Playgroud)


Jim*_*dra 3

我在当前正在开发的网站上遇到了同样的问题,并采用了您在底部提到的解决方案。如果您以编程方式生成 ID 并将整个表单放入部分表单中,则不会重复。例如,在我的网站上,每页有多个“条目”,每个条目都有两种投票形式,一种投赞成票,一种投反对票。每个条目的记录 ID 附加到其投票表单的 DOM ID 中,以使其唯一,如下所示(仅显示投票赞成按钮,投票反对按钮类似):

<% form_for [entry, Vote.new], :html => { :id => 'new_up_vote_' + entry.id.to_s } do |f| -%>
  <%= f.hidden_field :up_vote, :value => 1, :id => 'vote_up_vote_' + entry.id.to_s %>
  <%= image_submit_tag('/images/icon_vote_up.png', :id => 'vote_up_vote_submit' + entry.id.to_s, :class => 'vote-button vote-up-button') %>
<% end -%>
Run Code Online (Sandbox Code Playgroud)