Несколько форм для одной модели на одной странице - PullRequest
7 голосов
/ 07 февраля 2010

На первой странице моего сайта с объяснением рэп-лирики есть место, где пользователи могут попытаться объяснить сложную строку:

альтернативный текст 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>

Однако размещение более одного из них на одной странице проблематично, поскольку Rails автоматически присваивает каждой форме идентификатор new_feedback, а каждому полю - идентификатор типа feedback_body (что приводит к конфликтам имен)

Очевидно, я мог бы добавить что-то вроде :id => '' к форме и всем ее полям, но это, кажется, немного повторяется. Какой лучший способ сделать это?

Ответы [ 5 ]

11 голосов
/ 09 июля 2014

Если вы не хотите изменять свои входные имена или структуру модели, вы можете использовать опцию id, чтобы сделать ваш идентификатор формы уникальным, и опцию namespace, чтобы сделать ваши входные идентификаторы уникальными:

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

Таким образом, наш идентификатор формы уникален, то есть annotation_2_feedback, и это также добавит префикс, например, annotation_2_, к каждому входу, созданному через f.

6 голосов
/ 07 февраля 2010

Рассматривали ли вы nested_attributes для моделей рельсов? Вместо нескольких new форм обратной связи, каждая из которых связана с аннотацией, вы можете иметь несколько edit форм аннотации, где каждая аннотация содержит поля для новой обратной связи. Идентификаторы сгенерированных форм будут включать идентификатор аннотации, такой как edit_annotation_16.

Модель аннотации будет иметь отношение к своим обратным связям, а также будет принимать для них вложенные атрибуты.

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

class Feedback < ActiveRecord::Base
  belongs_to :annotation
end

Вы можете добавить столько форм, сколько хотите, по одной для каждой аннотации. Например, вот что я попробовал:

<% 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 %>

И быстрый и грязный контроллер для вышеупомянутого вида редактирования:

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
3 голосов
/ 07 февраля 2010

У меня была такая же проблема на сайте, над которым я сейчас работаю, и я остановился на решении, которое вы упомянули внизу. Это не повторяется, если вы генерируете идентификатор программно и помещаете всю форму в частичное. Например, на моем сайте у меня есть несколько «записей» на страницу, каждая из которых имеет две формы голосования, одну для голосования и одну для голосования. Идентификатор записи для каждой записи добавляется к идентификатору DOM его форм голосования, чтобы сделать его уникальным, например, так (просто показывает кнопку голосования вверх, кнопка голосования вниз аналогична):

<% 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 -%>
2 голосов
/ 18 сентября 2012

У меня тоже была та же проблема, но я хотел получить более расширяемое решение, чем добавление идентификатора в каждое поле. Поскольку мы уже используем form_for ... | f | нотация заключается в том, чтобы изменить имя модели, и вы получите новый префикс HTML ID.

Используя вариант этого метода: http://www.dzone.com/snippets/create-classes-runtime (я удалил & block вещи)

Я создаю новую модель, которая является точной копией модели, для которой мне нужна вторая форма на той же странице. Затем используйте эту новую модель для рендеринга новой формы.

Если первая форма использует

@address = Address.new

1012 * тогда *

create_class('AddressNew', Address)
@address_new = AddressNew.new

Ваш префикс идентификатора будет «address_new_» вместо «address_» для второй формы той же модели. Когда вы читаете параметры формы, вы можете создать модель адреса для помещения значений.

1 голос
/ 04 октября 2012

Для тех, кто спотыкается здесь, ищет решение для приложения Rails 3.2, посмотрите на этот вопрос:

Rails: использование form_for несколько раз (идентификаторы DOM)

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