如何在视图/索引上构建带有导轨的复选框 [英] how to build a tick box with rails on view/index

查看:44
本文介绍了如何在视图/索引上构建带有导轨的复选框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在视图/索引上构建一个带有导轨的复选框部分,这些是我迄今为止采取的所有步骤,我知道我需要对 routes.rb 做一些事情,你能帮忙吗?

I am trying to build a tick box section with rails on view/index,these are all the steps I've taken so far i know that i need to do something about routes.rb, can you help?

这是视图:

<table class="table table-hover">
      <thead>
        <tr>
          <th>Coupon</th>
          <th>first_name</th>
          <th>surname</th>
          <th>email</th>
          <th>occupation</th>
          <th>validation</th>
        </tr>
      </thead>
    <tbody>
      <% @scooties_coupons.each do |scooties_coupon| %>
        <tr>
          <td><%= scooties_coupon.coupon %></td>
          <td><%= scooties_coupon.first_name %></td>
          <td><%= scooties_coupon.surname %></td>
          <td><%= scooties_coupon.email %></td>
          <td><%= scooties_coupon.occupation %></td>
          <td><%= link_to "Mark as Valid", method: :patch %></td>
        </tr>
      <% end %>
    </tbody>
    </table>

(我知道标记为有效应该使用链接,但我不太确定链接到哪里)

(i know to mark as valid should use link to but i am not too sure where to link to)

 create_table "scooties_coupons", force: :cascade do |t|
    t.string "coupon"
    t.boolean "redeemed", default: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "email"
    t.integer "expires_in"
    t.string "first_name"
    t.string "surname"
    t.string "oppcupation"
    t.string "occupation"
    t.boolean "validated"
    t.index ["coupon"], name: "index_scooties_coupons_on_coupon"
  end

(我还在数据库中创建了经过验证的布尔值)

(I've also created the validated as boolean in the db)

这是控制器:

def update

     @scooties_coupon = ScootiesCoupon.find(scooties_coupon_params)
     @scooties_coupon.update( scooties_coupon_params
    redirect_to scooties_coupons_new_path

  end


  def scooties_coupon_params
    params.require(:scooties_coupon).permit(:first_name, :surname, :email, :occupation)

  end

推荐答案

感谢您的提问.其实做起来并不是那么简单.您想以一种形式编辑(来自)多条记录.

Thank you for your question. It is in fact not so simple to do. You want to edit (one attribute from) multiple records in one form.

稍微戳了一下,我想出了以下内容:

With a little poking, I came up with the following:

app/views/scooties_coupons/index.html.erb中:

<p id="notice"><%= notice %></p>

<h1>Scooties Coupons</h1>

<%= form_with(url: validate_coupons_path, method: 'patch') do |f| %>
  <table>
    <thead>
      <tr>
        <th>Valid</th>
        <th>Coupon</th>
        <th>Redeemed</th>
        <th>First name</th>
        <th colspan="3"></th>
      </tr>
    </thead>

    <tbody>
      <% @scooties_coupons.each do |scooties_coupon| %>
        <tr>
          <td>
            <%= fields_for('scooties_coupons[]', scooties_coupon) do |cf|
              cf.check_box(:validated)
            end %>
          </td>
          <td><%= scooties_coupon.coupon %></td>
          <td><%= scooties_coupon.redeemed %></td>
          <td><%= scooties_coupon.first_name %></td>
          <td><%= link_to 'Show', scooties_coupon %></td>
          <td><%= link_to 'Edit', edit_scooties_coupon_path(scooties_coupon) %></td>
          <td><%= link_to 'Destroy', scooties_coupon, method: :delete, data: { confirm: 'Are you sure?' } %></td>
        </tr>
      <% end %>
    </tbody>
  </table>
  <%= f.submit %>
<% end %>

<br>

<%= link_to 'New Scooties Coupon', new_scooties_coupon_path %>

包含一些技巧:

  • form_with(url: validate_coupons_path, method: 'patch') 在提交时向服务器设置补丁消息.
  • The form_with(url: validate_coupons_path, method: 'patch') sets-up a patch message to the server on submit.
  • The
fields_for('scooties_coupons[]', scooties_coupon) do |cf|
  cf.check_box(:validated)
end

为条目设置一个复选框.当您检查输出 HTML 时,您会发现以下两个字段:

sets-up a check box for an entry. When you check the output HTML you find two fields as follows:

<input name="scooties_coupons[1][validated]" type="hidden" value="0">
<input type="checkbox" value="1" checked="checked"
 name="scooties_coupons[1][validated]"
 id="scooties_coupons_1_validated">

  • <%= f.submit %> 提交按钮
  • app/controllers/scotties_coupons_controller.rb中:

    def set_valid_coupons
      to_valid = params[:scooties_coupons].select do |id, attrs|
        attrs[:validated] == '1'
      end
      to_not_valid = params[:scooties_coupons].reject do |id, attrs|
        attrs[:validated] == '1'
      end
      ScootiesCoupon.transaction do
        ScootiesCoupon.where(id: to_valid.keys, validated: false).update_all(
          validated:true)
        ScootiesCoupon.where(id: to_not_valid.keys, validated: true).update_all(
          validated:false)
      end
      redirect_to action: :index, notice: 'Validations updated'
    end
    

    是对参数的抓取,以进行两次更新,设置和清除记录上的 validated 标志,以便它们与修补的内容相对应.

    is a scraping of the params to make two updates that set and clear the validated flags on the records such that they correspond to what was patched.

    首先,to_valid 包含选中了 validated 复选框的参数选择.

    First, to_valid contains a selection of the params that have the validated check box checked.

    接下来,to_not_valid 包含未选中 validated 框的参数选择.当 validated 属性具有值时,会选中1".此代码将任何其他值视为检查.

    Next, to_not_valid contains a selection of the params that do not have the validated box checked. When the validated attribute has value, "1" it is checked. This code treats any other value as not checked.

    ScootiesCoupon.transaction do 块使两个从某种意义上说,它包含的更新几乎是原子的,如果第二个失败,ActiveRecord 将回滚第一个.

    The ScootiesCoupon.transaction do block makes the two updates that it contains virtually atomic in the sense that, if the second fails, ActiveRecord will roll back the first.

    第一次更新选择两者都具有的记录:

    The first update selects records that both have:

    • 与选中validated框的键匹配
    • 验证为 false
    • 的当前值
    • a key matching the ones with the validated box checked
    • a current value of validated as false

    它将这些记录更新为验证为 true

    It updates those records to value of validated as true

    第二次更新选择两个都具有的记录:

    The second update selects records that both have:

    • 与未选中validated框的键匹配
    • 验证为 true
    • 的当前值
    • a key matching the ones with the validated box not checked
    • a current value of validated as true

    它将这些记录更新为验证为 false

    It updates those records to value of validated as false

    通过仅更新需要更改的、与复选框的值不匹配的记录,代码避免更新表中的每条记录.然而,实际上,如果表中有那么多记录,索引视图将变得非常笨拙.有了成百上千的优惠券,浏览器就会有相当多的渲染,并为管理验证的人滚动.这是一个不同的问题,不同的问题.

    By only updating records that need changing, that don't already match the values of the check boxes, the code avoids updating every record in the table. In truth, however, if there are that many records in the table, the index view is going to become quite unwieldy. With hundreds or thousands of coupons there will be quite a bit of rendering for the browser and scrolling for the person administering validations. That is a different problem and different question.

    config/routes.rb 中:

    Rails.application.routes.draw do
      resources :scooties_coupons
      patch 'validate_coupons', to: 'scooties_coupons#set_valid_coupons'
    end
    

    添加用于修补记录的控制器操作.

    adds the controller action for patching up the records.

    索引显示为,例如:

    提交时,服务器控制台输出:

    On submit, the server console outputs:

    Started PATCH "/validate_coupons" for ::1 at 2019-06-25 17:12:58 -0300
    Processing by ScootiesCouponsController#set_valid_coupons as JS
      Parameters: {"utf8"=>"✓", "authenticity_token"=>"6Rk...rA==",
       "scooties_coupons"=>{
         "1"=>{"validated"=>"1"}, "2"=>{"validated"=>"0"},
         "3"=>{"validated"=>"0"}, "4"=>{"validated"=>"1"}
      }, "commit"=>"Save "}
       (0.1ms)  begin transaction
      ↳ app/controllers/scooties_coupons_controller.rb:60
      ScootiesCoupon Update All (0.4ms)  UPDATE "scooties_coupons"
     SET "validated" = 1
     WHERE "scooties_coupons"."id" IN (?, ?)
     AND "scooties_coupons"."validated" = ?
      [["id", 1], ["id", 4], ["validated", 0]]
      ↳ app/controllers/scooties_coupons_controller.rb:61
      ScootiesCoupon Update All (0.2ms)  UPDATE "scooties_coupons"
     SET "validated" = 0
     WHERE "scooties_coupons"."id" IN (?, ?)
     AND "scooties_coupons"."validated" = ?
      [["id", 2], ["id", 3], ["validated", 1]]
      ↳ app/controllers/scooties_coupons_controller.rb:63
       (0.1ms)  commit transaction
      ↳ app/controllers/scooties_coupons_controller.rb:60
    Redirected to http://localhost:3000/scooties_coupons?notice=Validations+updated
    Completed 200 OK in 5ms (ActiveRecord: 0.7ms)
    

    还有其他技巧可以在复选框被选中或取消选中时更新记录,无需提交,通过 AJAX;然而,从提交的表单开始,大部分方式都没有那么复杂.恐怕 AJAX 方式有点复杂.

    There are other tricks to get the record to update when the box is checked or unchecked, without the submit, via AJAX; however, starting with a submitted form gets most of the way there without that complication. The AJAX way is quite a bit of a complication, I'm afraid.

    查找:

    • Rails API 5.2.3 documentation for check_box at https://api.rubyonrails.org/v5.2.3/classes/ActionView/Helpers/FormBuilder.html#method-i-check_box
    • Rails 5.2 guidance about dealing with forms in Rails at https://guides.rubyonrails.org/v5.2/form_helpers.html

    这些在很长一段时间内都没有太大变化;所以很可能是相关的.

    These haven't changed much in a very long time; so are likely relevant.

    顺便说一句,控制器方法的以下实现可能看起来很诱人:

    As an aside, the following implementation of the controller method might look tempting:

    def set_valid_coupons
      update_params = {}
      params.require(:scooties_coupons).each do |id, attrs|
        update_params[id] = attrs.permit(:validated)
      end
      if (ScootiesCoupon.update(update_params.keys, update_params.values))
        redirect_to action: :index, notice: 'Validations updated'
      else
        redirect_to action: :index, alert: 'Updates failed'
      end
    end
    

    但是请注意,这会导致每条记录对数据库的几个命令,如下所示:

    However note that causes several commands to the database per record, as follows:

    Started PATCH "/validate_coupons" for 127.0.0.1 at 2019-06-25 15:33:29 -0300
    Processing by ScootiesCouponsController#set_valid_coupons as JS
      Parameters: {"utf8"=>"✓", "authenticity_token"=>"2Ecnb8Sy/5L4m9wW+4QlSS5WXQTCUh92ALRcv9w69OGRiov/Z95ReX9tGBn7UNN/NXSl83PeKs8cIkLaGhAoDg==", "scooties_coupons"=>{"1"=>{"validated"=>"1"}, "2"=>{"validated"=>"0"}, "3"=>{"validated"=>"0"}, "4"=>{"validated"=>"0"}}, "commit"=>"Save "}
      ScootiesCoupon Load (0.2ms)  SELECT  "scooties_coupons".* FROM "scooties_coupons" WHERE "scooties_coupons"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
      ↳ app/controllers/scooties_coupons_controller.rb:48
      ScootiesCoupon Load (0.1ms)  SELECT  "scooties_coupons".* FROM "scooties_coupons" WHERE "scooties_coupons"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
      ↳ app/controllers/scooties_coupons_controller.rb:48
      ScootiesCoupon Load (0.1ms)  SELECT  "scooties_coupons".* FROM "scooties_coupons" WHERE "scooties_coupons"."id" = ? LIMIT ?  [["id", 3], ["LIMIT", 1]]
      ↳ app/controllers/scooties_coupons_controller.rb:48
      ScootiesCoupon Load (0.1ms)  SELECT  "scooties_coupons".* FROM "scooties_coupons" WHERE "scooties_coupons"."id" = ? LIMIT ?  [["id", 4], ["LIMIT", 1]]
      ↳ app/controllers/scooties_coupons_controller.rb:48
       (0.0ms)  begin transaction
      ↳ app/controllers/scooties_coupons_controller.rb:48
       (0.0ms)  commit transaction
      ↳ app/controllers/scooties_coupons_controller.rb:48
       (0.0ms)  begin transaction
      ↳ app/controllers/scooties_coupons_controller.rb:48
       (0.0ms)  commit transaction
      ↳ app/controllers/scooties_coupons_controller.rb:48
       (0.0ms)  begin transaction
      ↳ app/controllers/scooties_coupons_controller.rb:48
       (0.0ms)  commit transaction
      ↳ app/controllers/scooties_coupons_controller.rb:48
       (0.0ms)  begin transaction
      ↳ app/controllers/scooties_coupons_controller.rb:48
       (0.0ms)  commit transaction
      ↳ app/controllers/scooties_coupons_controller.rb:48
    Redirected to http://localhost:3000/scooties_coupons?notice=Validations+updated
    Completed 200 OK in 15ms (ActiveRecord: 1.0ms)
    

    这篇关于如何在视图/索引上构建带有导轨的复选框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆