`
lzqustc
  • 浏览: 210328 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

Rails批量删除(更新)

阅读更多

  对于Rails web应用,涉及到最频繁的操作就是增、删、查、改操作,因此为了满足用户体验,批量删除(或更新)操作是必不可少。

在Rails自动生成的模板中,每个控制器(Controller)都包含7个基本Action,即index、show、new、create、edit、update、destroy,每个Action都只能处理一个对象,而批量操作必然要求能够处理多个对象,为此需要自定义一个批量操作的Action,下面就介绍如何在Rails中实现批量删除功能。

首先,客户要求批量删除功能的效果,如下图所示:

 

 

上图首先以表格的方式列出来库表(departs)里的所以记录(表格每一行,就代表库表的一条记录),然后每一行的第一列设置了一个单选框,用于标记是否选中此行,最后通过  “删除选中”链接,即可完成批量删除被选中记录功能,而且还通过JS实现了选中全部记录的功能。

要实现上面的效果,本人采用的一个解决方案,步骤如下:

①、通过 JS文件实现,“全选”和“反选”功能,js代码如下:

/*全选*/

function checkall (s,k){

   var a = document.getElementsByTagName('input'); 

   var n = a.length;

   for (var i=0; i<n; i++){

       if((a[i].type == "checkbox") && ( a[i].name.substr(0,k-1)==s )){ 

       a[i].checked = true;

     } 

   }

}

 

/*反选*/

function uncheck (s,k){

   var a = document.getElementsByTagName('input'); 

   var n = a.length;

   for (var i=0; i<n; i++){

     if((a[i].type == "checkbox") &&  (a[i].name.substr(0,k-1)==s) ){ 

       if(a[i].checked == true){

          a[i].checked = false;

       }

       else{ a[i].checked = true; } 

     }

   }

}

function doall (s,k,n ){

 if( k ){  checkall (s,n ) }

 else{ uncheck (s,n ) } 

}

而在视图中首先是设计每一行的checkbox的id,然后在最后一个代表“全选”的checkbox中调用上面代码的doall 方法,由参数的不同实现,全选和反选。代码片段如下:每一行的checkbox:

  <td width="5%" align='left' height='30' valign='middle' >

      <%= check_box_tag  ' depart_ '   + depart.id .to_s ,'yes',false %>    

  </td>

 

生成的html代码就是如下格式:

<input  id ="depart_ 7198 "  type ="checkbox "  value ="yes "  name ="depart_7198 " />

 

最后代表“全选”的checkbox:

<input id="all" type="checkbox" onclick="doall ( depart ,this.checked,7 );" /> 全选

 

其中,根据需求要选中的是所有 id 类似于"depart_ 7198 "的 checkbox,但是后面的 7198是 变化的为此应将所有id含有 depart_ checkbox都选择,那么就需要进行配备即JS中的 a[i].name.substr(0,k-1)==s) 7 就是字符串“ depart_ ”的长度

 

②、实现 “删除选中”链接的功能。

通过分析Rails模板自带的删除(destroy)Action,以及视图中实现“删除”链接的代码:<%= link_to '删除', depart, :confirm => '是否确定?', :method => :delete %>,可知其实使用了一个变量 :method,用它来表示 Http的DELETE动作。因为浏览器不支持DELETE动作,所以,Rails 会生成一些javascript来解决这个问题:例如下面的代码

 

link_to 删除 ,depart,:confirm => 是否确定? ,   :method => :delete 

 

会自动生成相应的javascript代码,如下:
<a href="/departs/1"
   onclick="var f = document.createElement( form );
   f.style.display = none ; this.parentNode.appendChild(f);
   f.method =  POST ; f.action = this.href;
   var m = document.createElement( input );
   m.setAttribute( type hidden );
   m.setAttribute( name , _method );
  m.setAttribute( value , ’delete’); 

  f.appendChild(m);f.submit(); return false;">删除</a>


     这段javascript代码会生成一个form,把 Http 的DELETE动作放在隐藏变量里传递给服务器,然后,Rails 会判断这个变量,决定是否去调用Controller的destroy 方法。

 

那么仿照这段javascript代码,并加以适当处理,使得其中的form,包含多个记录,再设置链接的地址,使其能提交给事先在Controller里自定义好的批量删除方法:destroy_selected,那么就能够实现批量删除的功能。

由于这部分代码是使用 link_to 这个Helper 方法来构造一个链接,那么我们要实现的批量删除链接,就应该是重载这个link_to方法,但是重载link_to方法可能影响到其它链接的生成,为此需要自定义一个Helper方法:destroy_selected (action_name,paramsname,obj_id,url),即在application_helper.rb中添加该方法,代码如下:

 

def destroy_selected  ( action_name,paramsname,obj_id,url )

    "<a onclick=\"if (confirm('是否确定?')){        

       var f = document.createElement('form');

       f.style.display = 'none';

       this.parentNode.appendChild(f);

       f.method = 'POST';

       var m = document.createElement('input');

       m.setAttribute('type', 'hidden');

       m.setAttribute('name', '_method');

        m.setAttribute('value', '#{action_name}');

       f.appendChild(m);

       var s = document.createElement('input');

       s.setAttribute('type', 'hidden');

       s.setAttribute('name', ' authenticity_token ');

       s.setAttribute('value', authenticity_token);

       f.appendChild(s);

       var a = document.getElementsByTagName('input');

       var n = a.length;

       ii = 0

       for (var i=0;i<n;i++){

        if((a[i].type == 'checkbox' )&& (a[i].checked == true ) && 

           (a[i].id != 'all')){

           var s = document.createElement('input');

           s.setAttribute('type', 'hidden');

            s.setAttribute('name', '#{paramsname}');

           s.setAttribute('value', a[i].name.slice(#{obj_id}) );

           f.appendChild(s);

           ii = ii + 1

         }

       }

       if (ii > 0){ f.action = this.href;  f.submit(); }

     };

    return false;\"  href=\"" + url_for(url).to_s+"\"  >删除选中</a> "

end

   

上面的代码主要处理了4个事件,即粗体部分:下面简要分析

    1)、 m.setAttribute('value', '#{action_name}');  根据传入的参数确

        定链接要提交的目标action.

    2)、 s.setAttribute('name', ' authenticity_token '); 由于Rails的安

        全机制,需要为该方法传入 authenticity_token。

3)、 s.setAttribute('name', '#{paramsname}');

    s.setAttribute('value', a[i].name.slice(#{obj_id}) );

     为form添加被选择的需要删除的记录,然后以参数形式,传给action。

4)、 href=\"" + url_for(url).to_s+"\", 设置链接地址。

 

根据上面的方法,在视图中的 “删除选中”链接代码就是

<%=destroy_selected ('destroy_selected ','depart_id[] ',7 [:destroy_selected,:departs]) %>

 

 

接下来就是,DepartsController里的destroy_selected方法了:

def destroy_selected

  respond_to do |format|

    if not params[:depart_id] .nil?

      begin 

        Depart.transaction do

          params[:depart_id].each do |did|

           if did != ""

              @depart = Departs.find(did)

              @depart.destroy

            end

          end 

        end 

        flash[:notice] = "删除数据成功!"     

      rescue     

        flash[:notice] = "删除数据失败!"     

      end    

    else 

      flash[:notice] = '请选择要删除的部门!'

    end

    format.html { redirect_to(departs_url) }

    format.xml  { head :ok }

  end

end

 

 

首先,根据前面的设计,“删除选择”链接提交时会通过form传出参数(数组):depart_id[],然后destroy_selected方法遍历depart_id[],再通过@depart = Departs.find(id);@depart.destroy 来逐个删除;为了保证数据安全和同步,代码中还使用了数据库的事务机制:Depart.transaction do,这样只要其中一条记录删除失败,那么所有记录都不会被删除。

 

最后,还要在路由中配置这个action的url ,即:

map.resources :departs,:collection => { :destroy_selected => :post}

 

这样,只要为数据库的每一张表对应的Controller都设计一个action——destroy_selected,那么就可以轻松地实现资源的批量删除工作。而其它批量操作(批量更新、排序....)都可以仿照上面的方法,加以实现。

        

  • 大小: 21.4 KB
分享到:
评论
6 楼 lzqustc 2013-03-05  
这个都是2009年的事了,估计当时的rails版本2.3.0比较低,所以....
5 楼 lzqustc 2013-03-05  
这个都是2009年的事了,估计当时的rails版本2.3.0比较低,所以....
4 楼 dohkoos 2012-12-14  
3 楼 chen_miao 2012-06-21  
请问你这是不是rails 3.2.1
2 楼 lzqustc 2011-02-15  
samwalt 写道
请问必须使用javascript才能实现吗?

以上只是我个人找到的一个解决方案,我相信一定有更好的实现方式(不一定必须用javascript)
1 楼 samwalt 2011-01-17  
请问必须使用javascript才能实现吗?

相关推荐

    batch_request_api, 在 Rails 应用程序上,提供批处理操作的ruby 中间件.zip

    batch_request_api, 在 Rails 应用程序上,提供批处理操作的ruby ...更新和删除的Rails 中间件 gem 。可以定制的中间件批量创建。更新和删除记录或者并行删除记录安装将此行添加到你的应用程序的Gemfile中:gem 'ba

    Ruby-RailsAdmin一个Rails引擎提供了一个易于使用的界面来管理您的数据

    1. 数据CRUD操作:RailsAdmin 提供了完整的创建(Create)、读取(Read)、更新(Update)和删除(Delete)功能,使得开发者可以通过简洁的界面直接对数据库中的数据进行操作。 2. 表单字段定制:开发者可以根据...

    bhl_rails_solr-源码.rar

    1. **索引创建与更新**:源码中的索引逻辑通常会覆盖ActiveRecord模型,使得在保存、更新或删除记录时,能自动同步到Solr索引。例如,`after_commit`回调可以用来确保数据库操作完成后更新索引。 2. **查询接口**:...

    Pro Active Record. Databases with Ruby and Rails

    - **批量操作**:讲解如何使用Active Record进行高效的批量数据插入、更新或删除。 - **事务管理**:解释如何利用Active Record的事务功能来确保数据操作的一致性和完整性。 4. **性能优化** - **懒加载与急加载...

    Agile Web Development with Rails中文版 3rd Edition

    建议定期更新Rails和相关的依赖库,以确保应用的安全性和稳定性。 **3.9 Rails和ISPs** 探讨了如何将Rails应用部署到互联网服务提供商(ISP)上,以及需要注意的一些问题。 #### 四、立竿见影 这部分通过一个...

    批量上传相册功能源码(包含各种语言)

    - **CRUD操作**:提供创建、读取、更新和删除相册及图片的接口。 - **权限管理**:用户对其相册的访问权限,如查看、编辑、删除等。 8. **用户体验优化** - **批量操作**:允许用户一次选择并操作多个图片,如...

    Ruby-Searchkick利用Rails和Elasticsearch轻松实现智能搜索

    `searchkick`模型方法提供了`update_index`和`destroy_index`,分别用于更新单个记录和删除记录的索引。 ### 7. 分页和分块 Searchkick支持Elasticsearch的分页和分块功能,这在处理大量数据时非常有用: ```ruby...

    浅谈Ruby on Rails下的rake与数据库数据迁移操作

    首先,Rails中的Migration是数据库结构变更的载体,它允许开发者通过编写代码来创建、修改或删除数据库表。每个Migration文件都包含一个时间戳,确保迁移的执行顺序,使得数据库结构始终与应用代码保持同步。然而,...

    ruby on rails 3.1.0数据库查询方法汇总

    12. **数据更新和删除**: - `c = Category.first` - `c.destroy` - 删除当前实例对应的数据库记录。 - `Category.delete(2)` - 直接删除 id 为 2 的记录。 - **注意**:`destroy` 方法会触发 ActiveRecord 的...

    2-Rails-sample_app

    12. **Scaffold**:Rails的生成器工具可以快速创建CRUD(创建、读取、更新、删除)操作的基础结构。 通过深入研究这个样本应用,初学者可以了解Rails的全貌,学习如何组织代码、设置路由、处理表单和响应、以及如何...

    在Ruby on Rails中优化ActiveRecord的方法

    ActiveRecord简化了数据库操作,允许开发者通过模型对象与数据库交互,这包括创建、读取、更新和删除数据。然而,随着应用规模的增长,性能优化变得至关重要。以下是一些在使用ActiveRecord时进行性能优化的关键点:...

    merchan-email-marketing:在 Rails 中创建的电子邮件营销系统

    1. **用户管理**:添加、编辑和删除用户,管理订阅者列表。 2. **模板设计**:创建和编辑电子邮件模板,以便进行品牌定制和一致的通信。 3. **邮件发送**:调度和发送批量电子邮件到订阅者列表。 4. **跟踪分析**:...

    购物参谋服务端软件使用说明书.docx

    1.2.2.8 批量上传:实现购物榜单的批量导入,服务器解析客户端请求,创建新的购物记录。 1.3 启动程序 服务端程序位于Script目录下的Server服务器,依赖于mysql 5.5版本数据库软件。 2. 服务器启动方法 2.1 第一种...

    bulk_discounts

    可以创建,更新和删除这些折扣。概述此Rails应用程序模拟一个商业智能应用程序,该应用程序显示记录及其关联的记录,并允许用户对这些记录执行CRUD操作。 资源展示了一对多和多对多的关系。Heroku部署状态:已部署...

    Ruby-actsasfollower允许任何ActiveRecord模型关注其他模型

    或者批量添加或删除关注: ```ruby # 批量关注 user.follow!(post1, post2, post3) # 批量取消关注 user.unfollow!(post1, post2, post3) ``` acts_as_follower 插件的灵活性使得在 Rails 应用中实现关注功能变得...

    penfold_2.10-0.1.17.zip

    5. 批量操作:提供批量插入、更新等功能,提高数据库操作性能。 6.事务处理:内置事务管理,保证数据的一致性和完整性。 在实际项目中,使用JActiveRecord可以大大减少数据库层的代码量,让开发者更专注于业务逻辑...

    xcode 中 CoreData的第三方包的使用 项目源码

    - **批量操作**:例如批量插入、更新和删除数据,避免频繁的数据库交互,提高性能。 - **错误处理**:许多库提供了更好的错误处理机制,使开发者更容易调试和解决问题。 - **事务支持**:第三方库可能提供了更...

    image-repo:对于Shopify 2021年夏季的开发实习生挑战。 这是一个构建为Web应用程序的图像存储库,用户可以在其中查看和上传他们的图像(一对一或批量),添加标题字幕并控制其公共_私人可见性

    此Web应用程序具有身份验证/授权功能,图像的安全上载/存储/删除,一对一或批量上载以及图像的访问控制。 它也已部署在Heroku上! 签出: : 如何使用注册一个帐户,在“上传”标签中上传1张或多张图片,然后填写...

    Ruby-chewy高级ElasticsearchRuby框架

    对于大量数据的操作,Chewy支持批量导入和删除,以提高性能。 ```ruby UsersIndex.client.bulk body: Users.all.map(&:as_indexed_json), refresh: true ``` 九、故障恢复与数据迁移 Chewy提供了工具帮助你在不同...

    购物参谋服务端软件使用说明书.doc

    - **批量上传**:支持购物记录的批量上传,服务器解析请求,新建数据库记录存储购物数据。 3. **启动程序** - **服务器端**:服务器端位于`Script`目录下的`Server`服务器。 - **数据库软件**:使用的是MySQL...

Global site tag (gtag.js) - Google Analytics