在Rails中同时编辑多个嵌套记录

时间:2010-02-24 05:18:53

标签: ruby-on-rails nested routes

我正在创建一个简单的测验应用程序,其中一个问题可以有多个答案。为了提高我的应用程序的可用性,我希望用户能够以相同的形式编辑给定问题的所有答案:

我发现这个很棒的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 %>  

但这在我的情况下不起作用,因为Answers依赖于问题......关于如何为我的嵌套模型翻译本教程的任何想法?

1 个答案:

答案 0 :(得分:1)

从某些角度来看,使用嵌套路线看起来很漂亮,但总是有点棘手。为了实现这一点,你必须

  1. 修复路线定义
  2. 在所有视图中调整URL生成器(例如form_for或answers_path)
  3. 路线

    首先要做的事情是:在路由中指定关联将不允许您向第二个类添加自定义路由。我会做这样的事情:

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

    浏览

    注意URL生成器的变化非常重要:

    • edit_answer_path(@answer) =&gt; edit_question_answer_path(@question,@ answer)
    • edit_individual_answer_path(@answer) =&gt; 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 %>
    

    附加

    正如您可能已经看到的那样,您需要在视图中使用变量@question,因此我建议您在AnswersController中使用before_filter来获取问题对象:

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

    享受您的嵌套路线!!