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
.
您是否考虑过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)
我在当前正在开发的网站上遇到了同样的问题,并采用了您在底部提到的解决方案。如果您以编程方式生成 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)