首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在具有唯一验证的记录之间交换值。

在具有唯一验证的记录之间交换值。
EN

Stack Overflow用户
提问于 2016-11-28 20:35:01
回答 2查看 791关注 0票数 1

场景

我有媒体比可以有许多音频轨道,我想存储的轨道在媒体中的顺序,但对于特定的媒体,序列必须是独特的。例如,一个Media对象可能有10个音轨,每个音轨的序列为1,2,。10

代码语言:javascript
运行
复制
class Medium < ActiveRecord::Base
  has_many   :tracks, inverse_of: :medium, dependent: :destroy
end

class Track < ActiveRecord::Base
  belongs_to :medium

  validates_uniqueness_of :sequence, scope: :medium, message: 'sequence is not unique for the medium'
end

然而,用户可以更改轨道序列,例如,他们将第二轨道移动到第8位置--这将导致轨道序列3-8减少1(分别变为2-7),而序列2变为轨道8。

问题

问题是,我不能简单地更改值并保存跟踪,因为当然验证失败了。

我唯一能想到的解决办法是:

  1. 用一个临时但唯一的序列号设置第一个已实现的轨道,并保存它。
  2. 减少其他音轨的序列号并保存它们。
  3. 用正确的序列号重新分配第一个音轨,并保存它。

然而,这似乎是非常低效的,而且只适合这一种情况。例如,我可以把轨道从第8位置移到第2位置。

理想情况下,我希望允许用户更改轨道上的序列,并修改其他数据,并且只有一次愉快地提交,这将导致调用将调用media.save的操作。

Rails中是否有更好的实践来处理此场景,或者它是否像看起来那样复杂。更好的做法是将此作为特例处理,并以原子方式处理每个更改--即一旦用户更改跟踪序列(调用父保存正在处理的其他跟踪属性更改,即.media.save)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-28 23:41:54

您可以使用充当列表宝石来解决排序和重新排序问题。

Gemfile

代码语言:javascript
运行
复制
gem 'acts_as_list'

medium.rb

代码语言:javascript
运行
复制
class Medium < ActiveRecord::Base
  has_many :tracks,
           -> { order(sequence: :asc) },
           inverse_of: :medium,
           dependent: :destroy
end

track.rb

代码语言:javascript
运行
复制
class Track < ActiveRecord::Base
  belongs_to :medium
  acts_as_list column: :sequence, scope: :medium
end
票数 3
EN

Stack Overflow用户

发布于 2016-11-28 22:03:01

您可以在父媒体记录上使用事务并执行所有更改,包括在一个块中重新编号序列。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40852962

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档