[Translation] 165: Batch Edit record (Edit Multiple)

165: Batch Edit record (Edit Multiple)

View original Railscast

Translator: darkbaby123

Proofreading: This is no proofreader, which brother if helpful and snails can contact students, or give me a message

52 sets demonstrated how to edit a number of examples of database records. Sample program that allows you to select more than one task once, then each of the selected task (Task) will be set to "complete."

[Translation] 165: Batch Edit record (Edit Multiple)

This focus on the idea that we would be expanded. But this time, we can let the user choose to update a group record number of properties, not on a set of individual attributes.

Online Store Application

The following shows that we have to transform the application. Currently, if we want to modify the form of the last two records, we must individually edit them. If you want to modify the record very few, this is not a problem. However, if faced with piles of records which is very boring. Now we will modify this procedure, it can also modify multiple attribute group record.

[Translation] 165: Batch Edit record (Edit Multiple)

Modify the index view

Each product before we will add a checkbox, so that we can easily choose to modify the product. But before that, we first show all the products table tag wrapped with form. At present we do not have a Controller level products used to edit multiple action, so first url address empty, and then later fill it.

<% form_tag ... do %>

We do not have to specify the form of presentation, so it defaults to POST. Although this form will take us to a display a new page for all selected products, we seem to be using GET, but because we want to pass the id number of products in the past, this is GET not.

Each row in the table, we need to add a checkbox, its value is the corresponding product id (even the title part in the table with an empty <th>, to ensure the form is aligned).

<td><%= check_box_tag "product_ids[]", product.id %></td>

Note check_box_tag's name, it is a square brackets at the end, it is up to all transfer values will be assembled in an array.

Finally, we add in the table below the submit button.

<%= submit_tag "Edit Checked" %>

Now our index view should look like:

<% form_tag ... do %>
    <% for product in @products %>
        <td><%= check_box_tag "product_ids[]", product.id %></td>
        <td><%= product.name %></td>
        <td><%= product.category.name %></td>
        <td><%= number_to_currency product.price, :unit => "&pound;" %></td>
        <td><%= link_to "Edit", edit_product_path(product) %></td>
        <td><%= link_to "Destroy", product_path(product), :confirm => "Are you sure?", :method => :delete %></td>
    <% end %>
<%= submit_tag "Edit Checked" %>
<% end %>
<%= link_to "New Product", new_product_path %>

Modify products controller

Our products controller contains useful RESTful action. Now we have to add two more action to edit and update records.

def edit_multiple

def update_multiple

The usefulness of these two action and standard edit and update about, but they used to deal with multiple records of the editing and updating. One edit_multiple method requires the corresponding view, we had a while to write it.

In our program, Products is a RESTful resources, we must modify the routes file so that the two new action can be accessed. Products because we want to add the collection method, we use: collection parameters to add these two methods.

map.resources :products, :collection => { :edit_multiple => :post, :update_multiple => :put }

: Collection parameters need to be a hash, where hash of key representatives of the name of action, the value of this action on behalf of the html method. As mentioned above, we use POST as edit_multiple the method, although ideally we should use GET.

Now our definition of good action, and we can return to index view, to fill in the correct url address form_tag

<% form_tag edit_multiple_products_path do %>

Now we refresh the index page, you can see the product in front of each checkbox, the following "Edit Checked" button will take us to the edit_multiple page.

[Translation] 165: Batch Edit record (Edit Multiple)

The new form

If we select some products, then click the "Edit Checked" button, you will see a missing template error. This is because we do not create the view code, so the next step is to complete it. We will view the code written in the / app / views / products / edit_multiple.html.erb file. But before we look at the click button, development of information generated in the log.

Processing ProductsController#edit_multiple (for at 2009-06-06 19:24:37) [POST]
  Parameters: {"product_ids"=>["3", "4", "5"], "commit"=>"Edit Checked", "authenticity_token"=>"s5z3KEJpBM7zC2JooC/relZ2oZtVpfxL/IMklpcBuYU="}

In the Parameters section, we can see our selected product id to an array of organizations with. In the controller, we will use these parameters to find the product selected before.

def edit_multiple
  @products = Product.find(params[:product_ids])

Turning now to our edit_multiple view. In our previous program, we have a partial on the form, it is used in new and edit product page. Looks like we can use this form to take over. But because it does some changes to accommodate batch records, so we simply create a new form.

In the view we first define the beginning of a block without closing the form_for (translators note: original writing form_tag, but the actual code is form_for, so translation to change a bit). Because this form is used to update multiple products, and we as its first parameter to specify a symbol instead of the actual Product object. We would also like for it specifies: url and: method (Note that PUT, it should be specified separately).

<% form_for :product, :url => update_multiple_products_path, :html => { :method => :put } do |form| %>

In the form we need to set all of the selected product id s, otherwise the submission form, we do not know which products will be updated. We can use a series of hidden_field_tag to store the product id s, we make a list to be updated to show these products.

  <% for product in @products %>
      <%= h product.name %>
      <%= hidden_field_tag "product_ids[]", product.id%>
  <% end %>

Next, we will add the form elements that form the properties of Product. These properties include the product name, category names, prices, and whether the sale of information. When we submit this form, we just want to update those who filled out the specific value of the property. Therefore, those with a choice of drop-down box, we need to add a blank option, so users can select an "empty" to skip these properties changes.

    <%= form.label :category_id %>
    <%= form.collection_select :category_id, Category.all, :id, :name, :include_blank => true %>
    <%= form.label :name %>
    <%= form.text_field :name %>
    <%= form.label :price %>
    <%= form.text_field :price %>
    <%= form.label :discontinued %>
    <%= form.select :discontinued, [["Yes", true], ["No", false]], :include_blank => true %>
    <%= form.submit "Submit" %>

Finally, we close the form_for the block, we have completed the form.

<% end %>

Now if we refresh the page, we will see our list of selected products, as well as the following product information is used to modify the form. Note that all of the drop-down boxes have been set to null value, so we do not go to modify their values in the database.

[Translation] 165: Batch Edit record (Edit Multiple)

Preparation for the updated action

We have now almost completed, but we need to write code for the update_multiple way, when the submission form on the map, update all selected products.

def update_multiple
  @products = Product.find(params[:product_ids])
  @products.each do |product|
    product.update_attributes!(params[:product].reject { |k,v| v.blank? })
  flash[:notice] = "Updated products!"
  redirect_to products_path

In update_multiple start, we use an array of products id s (from the hidden form fields transfer up to) get the selected products, and then we loop through and update each product. Because we only update the attributes is not empty, so we reject traversing each parameter and removed the value of empty property. Note that we use is with an exclamation point (!) Of update_attributes! Way, because we do not do any validation on the model. If this program is a real product, we do check, but beyond the scope of the discussion of this set. Use update_attributes! That if some data is not correct, the program will be thrown. All the products are updated once completed, we set up a flash message and then jump back to product list page.

Let us see if it can work. We have two products, Video Game Console and Video Game Disc, was placed on Toys & Games categories. Now we want to change Categories Electronics. If we select these two products and click "Edit Checked" button (Translator's Note: Original is the "Submit" button, but the actual page is the "Edit Checked"). We will see them listed in the edit_multiple page.

[Translation] 165: Batch Edit record (Edit Multiple)

If we choose from the category drop-down box, select "Electronics" and then click "Submit" button, we will return to product list page.

[Translation] 165: Batch Edit record (Edit Multiple)

You can see, these two product categories have been changed to "Electronics", but other properties are not changed.


Currently we have provided a very effective way to simultaneously edit multiple model objects. But in the end of this episode, we will go further, so the price can be a relative value to change. For example, so that we can reduce the price of all furniture 20%. We can now select more than one product, if we change the form of the price, then all of the products will become the same price. If we make use of virtual property, the logic of relative price change becomes very intuitive. Virtual property in the 16th concentrated presentations, if you want to know them, you can go to see the video or read the article .

Product model we will create a virtual attribute price_modification. We will modify the edit_multiple view form so that it will change our new property instead of directly modifying the price attribute.

  <%= form.label :price_modification %>
  <%= form.text_field :price_modification %>

Now we have to set a new model in the Product attribute getter and setter.

class Product < ActiveRecord::Base
  belongs_to :category

  def price_modification

  def price_modification=(new_price)
    if new_price.ends_with? "%"
      self.price += (price * (new_price.to_f / 100)).round(2)
      self.price = new_price

getter method is very straightforward: we only need to return to price on the line, but the setter method of a bit more complicated. If the input value (new_value) end with a percent sign, we will convert floating point values (new_price.to_f), divided by 100 and then multiplied by the original price, to find the price on the specific values. Then add it and the original price. If that specific value is negative, the price will fall. Finally, we use ActiveSupport extension round way for the new price to retain two decimal places.

Now, let us start or cheap furniture. We selected two of furniture and then modify them.

[Translation] 165: Batch Edit record (Edit Multiple)

Then in the "Price modification" column, fill in "-20%."

[Translation] 165: Batch Edit record (Edit Multiple)

When we submitted the form and return to the product list, we can see are lower prices for those products selected by 20%.

[Translation] 165: Batch Edit record (Edit Multiple)

Concentrate on the technology that is useful and can be used in a range of scenarios. After the experiment, you should be able to find in your Rails application in many places, can modify the properties are relatively useful.

分类:Ruby 时间:2010-03-09 人气:262
blog comments powered by Disqus


  • Database design - key and index 2010-08-11

    1. Data mining to pre-planned marketing department where I once have to deal with more than 80,000 copies of contact, while completing the necessary data for each client (this is not a small live). I also identified from a group of customers as the t

  • Random access database records 2010-12-06

    Randomly extracting N MySql database records select * from TableName order by rand () limit N Randomly extracting N SQLServer database records select top N * from TableName order by NEWID () Randomly extracting N Access database records SELECT top N

  • Database - Oracle trigger / stored procedure / view, etc. 2010-04-08

    1, Merge statement in the table under the conditions of the implementation of the function to modify or insert data, if the purpose of inserting rows of data exist in the table on the implementation of UPDATE, if it does not exist, the implementation

  • 2009-12-08 Chuan Chi podcast database - Oracle trigger / stored procedure / view, etc. (Reprinted) 2010-04-10

    1, Merge statement According to the conditions in the table to modify or insert data to perform the function, if the inserted data row in the destination table exists on the implementation of the UPDATE, if it does not exist, the implementation of IN

  • MySQL index view creation and deletion 2011-04-02

    MySQL index view creation and deletion 1. Index column in the index effect in addition to the above-mentioned order to find outside the database using a variety of quick positioning technology to greatly improve query efficiency. Especially when the

  • How quick access to oracle database records the number of rows in the table, do not use select count (1) mode 2010-11-17

    Database Version: Oracle 10G Today, the database query a table under the specific number of records, the use of select count (1) from [tablename], very slow to execute, so I want to see if there is a better way, find the table already exists in the t

  • How to quickly access the oracle database records the number of rows in the table, do not use select count (1) way 2010-11-21

    Database version: Oracle 10G Today, the database query in a table under the specific number of records, use select count (1) from [tablename], execute very slow, so I want to see if there is a better way to find the table already exists in the tabs o

  • Database records were extracted N 2010-02-28

    Remove the n random records: mysql: Select * From tablename order By rand() Limit n SqlServer: select top n * from tablename order by newid() Access: Select top n * FROM tablename orDER BY Rnd(id) Oracle: Select * from (select * from tablename order

  • Oracle database sql script new index 2010-04-20

    CREATE INDEX EMP_ENAME ON EMP(ENAME) TABLESPACE USERS STORAGE(INITITAL 20K NEXT 20K PCTINCREASE 75) PATFREE 0; Parameters: storage: the specified index is designated to establish the use of the storage allocation parameters initital: specified index

  • Pentaho platform to build the initialization mysql database - records the detailed steps 2010-07-11

    These days have been integrated in the school Pentaho BI Multidimensional Data Analyzer Mondrian OLAP engine and the query language MDX. Two days ago, just learning to use the Pentaho BI platform built environment, which initialize the database, this

iOS 开发

Android 开发

Python 开发



PHP 开发

Ruby 开发






Javascript 开发

.NET 开发



Copyright (C) codeweblog.com, All Rights Reserved.

CodeWeblog.com 版权所有 黔ICP备15002463号-1

processed in 0.385 (s). 10 q(s)