Редактирование нескольких вложенных записей одновременно в Rails - PullRequest
1 голос
/ 24 февраля 2010

Я создаю простое приложение для викторины, где вопрос может иметь несколько ответов. Чтобы повысить удобство использования моего приложения, я хочу, чтобы пользователи могли редактировать ВСЕ ответы на заданный вопрос в одной форме:

Я нашел этот замечательный эпизод Railscast / Asciicast, который почти ТОЧНО выполняет то, что я хочу сделать

http://asciicasts.com/episodes/198-edit-multiple-individually

Однако есть одна загвоздка. Моя модель ответов вложена в вопросы типа:

  map.resources :answers, :has_one => :question

  map.resources :questions, :has_many => :answers

Так что, когда придет время определить маршрут и тег формы, я немного отклеюсь ... Учебник предлагает создать 2 новых метода контроллера и определить маршруты и теги формы следующим образом:

map.resources :products, :collection => { :edit_individual => :post, :update_individual => :put } 

<% form_tag edit_individual_products_path do %>  

Но в моем случае это не работает, поскольку ответы зависят от вопросов ... Есть идеи, как перевести это руководство для моих вложенных моделей?

1 Ответ

1 голос
/ 25 февраля 2010

Работа с вложенными маршрутами выглядит довольно с некоторой точки зрения, но всегда становится немного сложнее. Для того чтобы это работало, вам нужно будет

  1. Исправить определение маршрута
  2. Адаптировать генераторы URL во всех представлениях (например, form_for или answers_path)

Маршруты

Перво-наперво: указание связей внутри маршрутов не позволит вам добавить пользовательские маршруты ко второму классу. Я бы сделал что-то вроде этого:

map.resources :questions do |question|
  question.resources :answers, :collection => {
     :edit_individual => :post, 
     :update_individual => :put }
end

Просмотры

Очень важно заметить изменение в генераторах URL:

  • edit_answer_path (@answer) => edit_question_answer_path (@question, @answer)
  • edit_individual_answer_path (@answer) => edit_individual_question_answer_path (@question, @answer)

Я сделал быструю адаптацию Railscasts просмотров:

<!-- views/answers/index.html.erb -->
<% form_tag edit_individual_question_answer_path(@question) do %>
  <table>
    <tr>
      <th></th>
      <th>Name</th>
      <th>Value</th>
    </tr>
  <% for answer in @answers %>
    <tr>
      <td><%= check_box_tag "answer_id_ids[]", answer.id %></td>
      <td><%=h answer.name %></td>
      <td><%=h answer.value %></td>
      <td><%= link_to "Edit", edit_question_answer_path(@question, answer) %></td>
      <td><%= link_to "Destroy", question_answer_path(@question, answer), :confirm => 'Are you sure?', :method => :delete %></td>
    </tr>
  <% end %>
  </table>
  <p>
    <%= select_tag :field, options_for_select([["All Fields", ""], ["Name", "name"], ["Value", "value"]]) %>
    <%= submit_tag "Edit Checked" %>
  </p>
<% end %>

<!-- views/answers/edit_individual.html.erb -->
<% form_tag update_individual_question_answers_path, :method => :put do %>
  <% for answer in @answers %>
    <% fields_for "answers[]", answer do |f| %>
      <h2><%=h answer.name %></h2>
      <%= render "fields", :f => f %>
    <% end %>
  <% end %>
  <p><%= submit_tag "Submit" %></p>
<% end %>

Extra

Как вы, возможно, уже видели, вам потребуется переменная @question в ваших представлениях, поэтому я бы порекомендовал вам иметь before_filter в вашем AnswerSontroller, который выбирает объект вопроса:

AnswersController
  before_filer :get_question

  [...]

  private
  def get_question
    # @question will be required by all views
    @question = Question.find(params[:question_id])
  end
end

Наслаждайтесь своими вложенными маршрутами !!

...