Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Ruby-交换两个ActiveRecord实例的主键?雅致_Ruby On Rails_Ruby_Activerecord_Primary Key_Swap - Fatal编程技术网

Ruby on rails Ruby-交换两个ActiveRecord实例的主键?雅致

Ruby on rails Ruby-交换两个ActiveRecord实例的主键?雅致,ruby-on-rails,ruby,activerecord,primary-key,swap,Ruby On Rails,Ruby,Activerecord,Primary Key,Swap,小问题。。。这是为了解决什么是一个简单的黑客和似乎愚蠢的不修复 如果有两个从ActiveRecord派生的同一类的项,如何交换它们的主键?下面的代码可以工作,但请看 class Item < ActiveRecord::Base self.primary_keys = :p_key def self.swap( a, b ) return if a.nil? or a.nil? # fix this hack! temp_1 = a.p_key

小问题。。。这是为了解决什么是一个简单的黑客和似乎愚蠢的不修复

如果有两个从ActiveRecord派生的同一类的项,如何交换它们的主键?下面的代码可以工作,但请看

class Item < ActiveRecord::Base
  self.primary_keys = :p_key

  def self.swap( a, b )
    return if a.nil? or a.nil?

    # fix this hack!
    temp_1 = a.p_key
    a.p_key = "999999" #these keys cannot ever occur in our software... promise!
    a.p_key.save!
    a.p_key = b.p_key
    b.p_key = temp_2
    b.save!
    a.save!
  end
end
ActiveRecord(与任何其他ORM一样)不允许更改主键。如果您将以某种方式对其进行更改,那么您的模型实例将引用不同的数据库记录(如果存在)

例如,假设您有一个具有主键10的项模型实例。如果更改任何字段并保存模型,ActiveRecord将生成一条SQL语句,如
UPDATE。。。设置其中id=10
。此语句将更新id为10的数据库行

如果您以某种方式将主键更改为20,那么ActiveRecord将生成一条SQL语句,如
UPDATE。。。设置其中id=20
。此语句更新另一行(如果存在),保持id=10的行不变

要更改主键,必须执行如下SQL语句:
updatemyu table SET id=20,其中id=10
。之后,您将需要重新加载id为10和20的模型实例

编写一个SQL语句来交换两个数据库行的主键,这将有点棘手(但是可能,这取决于您的DB服务器)。但是ActiveRecord不会帮助您


你为什么需要这个?这个问题看起来很奇怪,所以我想您实际上还需要其他东西。

假设您想交换键值1和键值2。在标准SQL中:

UPDATE tbl SET keycol = CASE keycol WHEN 1 THEN 2 WHEN 2 THEN 1 END
WHERE keycol IN (1,2);
您也可以用另一种方法来解决这个问题,交换每个非键列的值——当然,这最终也会产生相同的效果。这里有一种方法,但不幸的是,它不是标准的SQL。它适用于SQL Server和其他可能的应用程序,但我还没有在其他地方测试过它。为了在标准SQL中实现同样的效果,我认为您必须创建一个视图来代替派生表子查询

UPDATE t SET x1 = x2, y1 = y2, z1 = z2
FROM
(
  SELECT t1.keycol keycol1, t2.keycol keycol2,
  t1.x x1, t1.y y1, t1.z z1, t2.x x2, t2.y y2, t2.z z2
  FROM tbl t1, tbl t2
  WHERE (t1.keycol = 1 AND t2.keycol = 2)
  OR (t1.keycol = 2 AND t2.keycol = 1)
) t;

在更高的层次上,你想做什么?
UPDATE t SET x1 = x2, y1 = y2, z1 = z2
FROM
(
  SELECT t1.keycol keycol1, t2.keycol keycol2,
  t1.x x1, t1.y y1, t1.z z1, t2.x x2, t2.y y2, t2.z z2
  FROM tbl t1, tbl t2
  WHERE (t1.keycol = 1 AND t2.keycol = 2)
  OR (t1.keycol = 2 AND t2.keycol = 1)
) t;