如何在表中更新几行最小数量的数据库查询

时间:2015-07-19 19:35:10

标签: ruby-on-rails ruby ruby-on-rails-4 activerecord

拥有一组类别,表示为对象集合。每个对象都有一个sort属性。此属性采用从1到数字的数值,该数字是集合的最后一个元素。有一个按排序属性

过滤的类别列表
linecategories=Linecategory.eager_load(:main_image).order('sort')

然后将此列表拖动拖动并将一定数量的对象拖到集合中,这样就会改变此属性排序的值。此外,ajax从2到n的对象的属性发生了变化。 要执行的任务更新数据库中已更改的字段。 现在数据的形式为:

data={}
data['items']=params[:data]

数据的格式为

data: [{id: 1, name: "Гороскопы", slug: "horoscopes", title: "keywords-horoscopes",…},…]
0: {id: 1, name: "Гороскопы", slug: "horoscopes", title: "keywords-horoscopes",…}
created_at: "2015-01-10T21:14:56.000Z"
description: "description-horoscopes"
id: 1
keywords: "keywords-horoscopes"
name: "Гороскопы"
slug: "horoscopes"
sort: 1
title: "keywords-horoscopes"
updated_at: "2015-07-19T19:10:03.000Z"
1: {id: 5, name: "Гадания", slug: "divination", title: "eywords-divination",…}
created_at: "2015-01-11T08:47:10.000Z"
description: "2015-01-11 08:47:10"
id: 5
keywords: "description-divination"
main_image: {id: 1, src: "images/categories_images/devination.jpg", linecategory_id: 5, created_at: null,…}
name: "Гадания"
slug: "divination"
sort: 2
title: "eywords-divination"
updated_at: "2015-07-19T19:24:23.000Z"
2: {id: 3, name: "Вкусности", slug: "delicious", title: "keywords-delicious",…}
created_at: "2015-01-10T21:17:28.000Z"
description: "2015-01-10 21:17:28"
id: 3
keywords: "description-delicious"
name: "Вкусности"
slug: "delicious"
sort: 3
title: "keywords-delicious"
updated_at: "2015-07-19T19:24:23.000Z"

现在我实现了这样的更新:

def updates
    data={}
    data['items']=params[:data]
    data['items'].each { |el|
      @item=Linecategory.find(el['id'])
      @item.update_attributes(el.permit(:sort))
    }
    render json: {update: 1, data: data['items']}
  end

但我认为这不是最佳解决方案,我认为通过ruby on rails和activerecords可以更有效,更美观地完成这个问题,如果可能的话,建议解决问题?

2 个答案:

答案 0 :(得分:0)

  def updates
    data=params[:data].as_json(only: [:id, :sort])
    h = {}
    data.each_with_index { |e, i| h[e['id']] = e }
    Linecategory.update(h.keys, h.values)
    render json: {update: 1, data: h}
  end

Mine找到了解决方案,我仍然没有katsa完全优化,因为在更新之前我必须使用: data.each_with_index {| e,i | h [e ['id']] = e} 但即便如此,它仍然有效。 继续设置更新数据库的合理查询,但是女朋友可以做到吗?

 Linecategory Load (0.4ms)  SELECT  `linecategories`.* FROM `linecategories`  WHERE `linecategories`.`id` = 6 LIMIT 1
       (0.3ms)  BEGIN
      Linecategory Exists (0.4ms)  SELECT  1 AS one FROM `linecategories`  WHERE (`linecategories`.`slug` = BINARY 'our_dreams' AND `linecategories`.`id` != 6) LIMIT 1
      SQL (0.2ms)  UPDATE `linecategories` SET `sort` = 1, `updated_at` = '2015-07-20 21:07:47' WHERE `linecategories`.`id` = 6
       (2.3ms)  COMMIT
      Linecategory Load (0.5ms)  SELECT  `linecategories`.* FROM `linecategories`  WHERE `linecategories`.`id` = 4 LIMIT 1
       (0.3ms)  BEGIN
      Linecategory Exists (0.7ms)  SELECT  1 AS one FROM `linecategories`  WHERE (`linecategories`.`slug` = BINARY 'beauty_and_health' AND `linecategories`.`id` != 4) LIMIT 1
      SQL (0.3ms)  UPDATE `linecategories` SET `sort` = 2, `updated_at` = '2015-07-20 21:07:47' WHERE `linecategories`.`id` = 4
       (1.0ms)  COMMIT
      Linecategory Load (0.2ms)  SELECT  `linecategories`.* FROM `linecategories`  WHERE `linecategories`.`id` = 1 LIMIT 1
       (0.2ms)  BEGIN
      Linecategory Exists (0.7ms)  SELECT  1 AS one FROM `linecategories`  WHERE (`linecategories`.`slug` = BINARY 'horoscopes' AND `linecategories`.`id` != 1) LIMIT 1
      SQL (0.2ms)  UPDATE `linecategories` SET `sort` = 3, `updated_at` = '2015-07-20 21:07:47' WHERE `linecategories`.`id` = 1
       (0.9ms)  COMMIT
      Linecategory Load (0.4ms)  SELECT  `linecategories`.* FROM `linecategories`  WHERE `linecategories`.`id` = 2 LIMIT 1
       (0.3ms)  BEGIN
      Linecategory Exists (0.4ms)  SELECT  1 AS one FROM `linecategories`  WHERE (`linecategories`.`slug` = BINARY 'test_yourself' AND `linecategories`.`id` != 2) LIMIT 1
      SQL (0.5ms)  UPDATE `linecategories` SET `sort` = 4, `updated_at` = '2015-07-20 21:07:48' WHERE `linecategories`.`id` = 2
       (0.9ms)  COMMIT
      Linecategory Load (0.3ms)  SELECT  `linecategories`.* FROM `linecategories`  WHERE `linecategories`.`id` = 5 LIMIT 1
       (0.2ms)  BEGIN
      Linecategory Exists (0.5ms)  SELECT  1 AS one FROM `linecategories`  WHERE (`linecategories`.`slug` = BINARY 'divination' AND `linecategories`.`id` != 5) LIMIT 1
      SQL (0.2ms)  UPDATE `linecategories` SET `sort` = 5, `updated_at` = '2015-07-20 21:07:48' WHERE `linecategories`.`id` = 5
       (0.8ms)  COMMIT
      Linecategory Load (0.3ms)  SELECT  `linecategories`.* FROM `linecategories`  WHERE `linecategories`.`id` = 7 LIMIT 1
       (0.1ms)  BEGIN
      Linecategory Exists (0.4ms)  SELECT  1 AS one FROM `linecategories`  WHERE (`linecategories`.`slug` = BINARY 'what_is_it_in_my_name' AND `linecategories`.`id` != 7) LIMIT 1
      SQL (0.2ms)  UPDATE `linecategories` SET `sort` = 6, `updated_at` = '2015-07-20 21:07:48' WHERE `linecategories`.`id` = 7
       (0.9ms)  COMMIT
      Linecategory Load (0.3ms)  SELECT  `linecategories`.* FROM `linecategories`  WHERE `linecategories`.`id` = 3 LIMIT 1
       (0.2ms)  BEGIN
      Linecategory Exists (0.4ms)  SELECT  1 AS one FROM `linecategories`  WHERE (`linecategories`.`slug` = BINARY 'delicious' AND `linecategories`.`id` != 3) LIMIT 1
      SQL (0.3ms)  UPDATE `linecategories` SET `sort` = 7, `updated_at` = '2015-07-20 21:07:48' WHERE `linecategories`.`id` = 3
       (1.0ms)  COMMIT

答案 1 :(得分:0)

我找到了更好的方法

# /admin_categories PUT
  def updates
    data=params[:data].as_json(only: [:id, :sort])
    db = ActiveRecord::Base.connection()
    ids=[]
    query = "UPDATE linecategories SET sort = CASE id "
    data.each_with_index do |e, i|
      query += ActiveRecord::Base.send(:sanitize_sql_array,["WHEN ? THEN ? ", e['id'], e['sort']])
      ids.push e['id']
    end
    query += "END "
    query += "WHERE id in (#{ids.join(",")}) "
    db.execute(query)
    render json: {}
  end