book
has_many
pages
。页面具有属性page_no
。我想在本书的任意两个页面(x,y)之间添加PageAt(z),为此,我必须先将书籍的所有页面从y更新到book.pages.count,然后再创建 - >保存页面( Z)。
以下是单次运行更新的SQL:
sql = "update pages set page_no = page_no+1 where book_id =" + (@book.id).to_s + " and page_no >" + (@addPageAt - 1).to_s
records_arraty = ActiveRecord::Base.connection.execute(sql)
有效!但要做到这一点,我必须从pages
表中删除以下验证:
validates :book_id, presence: true, on: :save
validates :page_no, presence: true, uniqueness: true, on: :save
validates_uniqueness_of :page_no, :scope => :book_id
我想保留这些验证,特别是第三个验证。怎么做?
答案 0 :(得分:1)
一种方法是两个单独的更新:
update pages
set page_no = - (page_no + 1)
where book_id = " + (@book.id).to_s + " and page_no >" + (@addPageAt - 1).to_s;
update pages
set page_no = - page_no
where where book_id = " + (@book.id).to_s " and page_no < 0);
您可以在单个交易中执行此操作,因此负页码永远不可见。
答案 1 :(得分:1)
你需要:
OR
在单个SQL语句中运行这两个UPDATE:
"WITH a
AS (
UPDATE pages
SET page_no = - (page_no + 1)
WHERE book_id = " + (@book.id).to_s + "
AND page_no > " + (@addPageAt - 1).to_s + "
RETURNING *
), b AS (
UPDATE pages
SET page_no = - page_no
WHERE book_id = " + (@book.id).to_s + "
AND page_no < 0
RETURNING *
)
SELECT 1
FROM a, b
LIMIT 1;"
答案 2 :(得分:0)
您可以尝试将ORDER BY page_no DESC
添加到更新查询中。从最后一个到第一个工作时,没有重复page_no
。