在轨道中删除多条记录

问题描述:

我正在研究一个允许用户选择多个条目的应用程序。一旦选择了这些条目,用户可以选择全部删除它们。当点击删除按钮(在选择一个或多个条目后)时,会显示一个模式对话窗口,显示用户用确认按钮选择的条目。在轨道中删除多条记录

目前,以上所有内容都是在客户端上使用jQuery完成的。我已设法完成所有设置,以便确认按钮(使用:method => :deletelink_to)的URL为/entries/12,13,16,17,其中数字表示用户所选条目的ID。我也试着发送格式为/entries/[1,2,3,4]的网址,但没有运气。我有一种感觉,我不是发送真实阵列。

这里是我的删除方法,当使用一个ID,其工作完全正常(即/entries/1),并且将有希望继续与一个ID的工作:

def destroy 
@entry = current_user.entries.find(params[:id]) 
@entry.destroy 

respond_to do |format| 
    format.html { redirect_to(entries_url) } 
    format.xml { head :ok } 
end 
end 

当我发送多个ID的(在格式1,2,3,4,5),只有第一个条目被删除,而其余条目保持不变。这里是我的WEBrick日志看起来像表演动作后:

Processing EntriesController#destroy (for 127.0.0.1 at 2009-12-03 23:07:24) [DELETE] 
    Parameters: {"action"=>"destroy", "_method"=>"delete", "id"=>"19,22", "controller"=>"entries"} 
    User Load (0.3ms) SELECT * FROM "users" WHERE ("users"."id" = '2') LIMIT 1 
    User Update (0.3ms) UPDATE "users" SET "updated_at" = '2009-12-04 04:07:24', "last_request_at" = '2009-12-04 04:07:24' WHERE "id" = 2 
    Entry Load (0.2ms) SELECT * FROM "entries" WHERE ("entries"."id" = 19 AND ("entries".user_id = 2)) 
    Tagging Load (0.4ms) SELECT * FROM "taggings" WHERE ("taggings".taggable_id = 19 AND "taggings".taggable_type = 'Entry' AND (taggings.context = 'tags')) 
    Tag Load (0.2ms) SELECT * FROM "tags" WHERE ("tags"."id" IN (22,23,24,29)) 
    Tagging Destroy (0.2ms) DELETE FROM "taggings" WHERE "id" = 66 
    Tagging Destroy (0.1ms) DELETE FROM "taggings" WHERE "id" = 67 
    Tagging Destroy (0.0ms) DELETE FROM "taggings" WHERE "id" = 68 
    Tagging Destroy (0.1ms) DELETE FROM "taggings" WHERE "id" = 69 
    Tagging Load (0.1ms) SELECT * FROM "taggings" WHERE ("taggings".taggable_id = 19 AND "taggings".taggable_type = 'Entry') 
    Entry Destroy (0.1ms) DELETE FROM "entries" WHERE "id" = 19 
    Entry Load (0.5ms) SELECT * FROM "entries" WHERE ("entries".user_id = 2) 
Redirected to http://localhost:3000/entries 

正如你所看到的,这些ID发送("id"=>"19,22"),但只有第一个项目被装载。之后,其关联的标记将被删除(我正在使用acts_as_taggable_on插件)。然后,第一个条目(id => 19)被销毁,用户被重定向回到条目列表页面。

应该做的是对每个传递的id重复该过程(重定向)。我很困惑,因为RoRs docs状态:

ID - 可以是一个整数或 整数数组。

我在做什么错?我觉得我好亲近,我可以品尝它!对我来说,获得所有jQuery的工作是一个巨大的胜利,所以现在我知道控制器方法中处理多个id的唯一缺失。

任何帮助将不胜感激!

您可以解析出params [:id]并从中创建一个数组,然后使用它。

快速修复:

我个人将发送ids不同的方式,但我不想弄糟你的路由。因此,这将工作,但我只能解决部分destroy

current_user.entries.destroy(params[:id].split(',')) 

这使得其作用范围current_user而是直接与IDS的数组调用destroy功能。

更好的方式:

如何我可能会建议使它更明显的是这样的:

相反的/entries/12,13,16,17我会用/entries/multiple?del[]=12&del[]=13&del[]=16&del[]=17

我知道这是更长的时间,但它更符合轨道如何自然运作。然后,控制器上:

def destroy 
    id = params[:id] 
    id = (params[:del] || []) if(id == "multiple") 

    current_user.entries.destroy(id) 

    respond_to do |format| 
    format.html { redirect_to(entries_url) } 
    format.xml { head :ok } 
    end 
end 

现在你的功能支持正常的单destroy行动以及你的新的多destroy

+0

这打破了RESTful约定,应该放在另一个操作中。 – bensie 2009-12-04 05:01:36

有一个ActiveRecord方法来做你想要的 - 你可以看看destroy_all。它期望删除一个字符串,数组或散列的id。

我常添加其他动作控制器为destroy_multiple - 不要忘记添加回收路径以及:

def destroy_multiple 
    current_user.entries.destroy_all(:id => params[:user_ids]) 
    redirect_to entries_url 
end 
+0

关于单独操作的好处,但'destroy'会适合这里的需求,因为它接受单个ID或数组。 – 2009-12-04 05:13:41

+0

+1以获得最佳答案。对不起,先挑选:) – 2009-12-04 05:24:11

下面是一个朋友帮我想出了:

def destroy 
    params[:id].split(',').each do |id| 
     @entry = current_user.entries.find(id) 
     @entry.destroy 
    end 

    respond_to do |format| 
     format.html { redirect_to(entries_url) } 
     format.xml { head :ok } 
    end 
end 

我敢肯定,这可能会更好,更有效地完成,但对于Alpha来说,这会起作用。感谢大家的帮助!

+0

“效率低下”,因为它为每个'find'单独调用数据库,而不是一次完成它们。 – 2009-12-04 05:21:34

+0

我确实尝试了上面的解决方案,而他们都没有做到这一点。我真的非常感谢您为帮助我而付出的时间和精力。我真的不想浪费任何人的时间。我确信上述解决方案将来会派上用场,但现在我需要快速开展工作。我希望你能理解并再次感谢。 – shaunandrews 2009-12-04 05:39:26

+0

@shaunandrews对于尝试解决方案感到沮丧。我正在删除我原来的评论,所以我可以感觉不到一个混蛋:) – 2009-12-04 05:59:09

您是否尝试调试并检查@entry中返回的内容。我想你可能没有得到整个阵列。你可以尝试使用ruby-debug插件来调试你的代码。 请注意,使用GET进行删除可能会产生not be the best选项