【问题标题】:Multiple non-nested model creation on same page在同一页面上创建多个非嵌套模型
【发布时间】:2013-05-30 23:02:14
【问题描述】:

有没有办法在同一个页面上创建多个模型而不嵌套在另一个页面中?

例如,我想要一个可以创建用户的表单。它有两个简单的字段,名字和姓氏,显示在同一行。我希望能够添加一个“添加新用户”链接,该链接将创建(使用 javascript)一个相同的行而无需回发,并允许我在同一页面提交上创建两个用户。

如何使用 Rails 实现这一点?

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    添加字段,只保留一个表单,一个提交按钮:

    = form_tag(url: create_user_path, remote: true) do
      %table
        %tr
          %td= text_field_tag 'user[][first_name]'
          %td= text_field_tag 'user[][last_name]'
    
        %tr.actions
          %td= submit_tag 'Save'
          %td= button_tag 'Add new user form', id: 'add_user_form'
    
        %tr.new_user_row.hidden # hidden class matches the css rule: {display:none;}
          %td= text_field_tag "user[][first_name]"
          %td= text_field_tag "user[][last_name]"
    
    :javascript # jQuery
      $('#add_user_form').bind('click', function(e) {
        var row = $('tr.new_user_row').clone().removeClass('hidden new_user_row');
        $('tr.actions').before(row); # will append the <tr> before the actions
      });
    

    在用户控制器中:

    def create
      params[:user].each do |attr|
        User.create(attr)
      end
    end
    

    tr.new_user_row.hidden 行用作新行的模板:通过单击按钮#add_user_form,JS 代码将选择模板行,clone 它并添加这个带有空输入的新行作为表格的最后一个可见行。

    【讨论】:

    • 每个表单包含一个提交按钮。我想要一个提交按钮来创建多个用户。
    • 感谢@MrYoshiji 提供此解决方案。这是我能找到的最干净的一个。我仍然认为替换部分很笨重,但还没有其他选择。我正在考虑使用一个接受 id 参数的部分并使用异步请求获取它,但这将涉及对服务器的获取操作。您的解决方案只是使用本地模板,这样更快。
    • 我已经玩了一点,找到了一个更清洁的解决方案,无需替换!我更新了你的答案。在 rails doc 中:“如果参数名称包含一组空方括号 [],那么它们将累积在一个数组中。”
    • @JohnSam 这个答案可能对您有所帮助,是的,它似乎与 strong_parameters stackoverflow.com/questions/17335329/… 相关联(您必须允许 params[:user] 键的数组(或 params[:users],具体取决于您使用的名称)
    • @JohnSam 你必须手动编译一个大的 SQL 插入语句,绕过 Rails 的工具 (ActiveRecord)。我不建议这样做,因为对每个都做一个 instert 还不错,并且手动执行 SQL 查询会导致各种问题(SQL 注入、创建时错误的属性分配、语法错误等)。
    【解决方案2】:

    用一种模型在一种形式中创建多条记录

    这里是users_controller.rb

     def new
     end
     def create_multiple
        params[:users].each do |user|
         user = User.create(user)
        end
        redirect_to users_url
      end
    

    这里是new.html.erb

    <%= form_tag '/users/create_multiple' do %>
    
      <%= render 'user_fields' %>
      <div class="actions">
        <%= submit_tag %>
      </div>
    <% end %>
    

    这里是_user_fields.html.erb

    <script type="text/javascript">
    $(function() {
            var scntDiv = $('#addusers');
            var i = $('#addusers div').size() + 1;
    
            $('#addfields').on('click', function() {
                    $('<div class="field"><h2>User ' + i +'</h2><input id="users__firstname' + i +'" name="users[][firstname]" placeholder="first name" type="text" /><input id="users__lastname' + i +'" name="users[][lastname]" placeholder="last name" type="text" /></div>').appendTo(scntDiv);
                    i++;
                    return false;
            });
    
    
    });
    
    </script>
    <div id="addusers">
    <div class="field">
     <h2>User 1</h2>
     <%= text_field_tag "users[][firstname]", nil, :placeholder => "first name" %>
     <%= text_field_tag "users[][lastname]", nil, :placeholder => "last name" %>
    </div>
    </div>
    
    <a href="#" id="addfields">Add a New User</a><br/>
    

    日志结果

    Started POST "/users/create_multiple" for 127.0.0.1 at 2013-06-05 00:40:07 +0700
    
    Processing by UsersController#create_multiple as HTML
      Parameters: {"utf8"=>"V", "authenticity_token"=>"xOPM6PB1h6DMUEGS7fX9/eWs/e6dg
    XKRj231ReviKFo=", "users"=>[{"firstname"=>"test1", "lastname"=>"last1"}, {"first
    name"=>"test2", "lastname"=>"last2"}], "commit"=>"Save changes"}
      ←[1m←[36m (78.0ms)←[0m  ←[1mbegin transaction←[0m
      ←[1m←[35mSQL (49.0ms)←[0m  INSERT INTO "users" ("created_at", "firstname", "la
    stname", "updated_at") VALUES (?, ?, ?, ?)  [["created_at", Tue, 04 Jun 2013 17:
    40:08 UTC +00:00], ["firstname", "test1"], ["lastname", "last1"], ["updated_at",
     Tue, 04 Jun 2013 17:40:08 UTC +00:00]]
      ←[1m←[36m (7.0ms)←[0m  ←[1mcommit transaction←[0m
      ←[1m←[35m (0.0ms)←[0m  begin transaction
      ←[1m←[36mSQL (3.0ms)←[0m  ←[1mINSERT INTO "users" ("created_at", "firstname",
    "lastname", "updated_at") VALUES (?, ?, ?, ?)←[0m  [["created_at", Tue, 04 Jun 2
    013 17:40:08 UTC +00:00], ["firstname", "test2"], ["lastname", "last2"], ["updat
    ed_at", Tue, 04 Jun 2013 17:40:08 UTC +00:00]]
      ←[1m←[35m (5.0ms)←[0m  commit transaction
    Redirected to http://localhost:3000/users
    Completed 302 Found in 156ms (ActiveRecord: 142.0ms)
    

    您可以根据自己的意愿添加验证码,这里是如何为多条记录传递表单参数basic-structures

    【讨论】:

    • 感谢您的回答。这很像@MrYoshiji 的回答。您在他使用模板时动态构建 html。您的解决方案有效,但我认为他的解决方案更清洁。
    • 这种方法对验证错误的处理尚不清楚。
    猜你喜欢
    • 1970-01-01
    • 2015-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多