Ruby on rails 在具有唯一验证的记录之间交换值
场景 我的媒体可以有很多音轨,我想在媒体中存储音轨序列,但对于特定媒体,序列必须是唯一的。因此,例如,一个媒体对象可能有10个磁道,每个磁道的序列为1,2。。十,Ruby on rails 在具有唯一验证的记录之间交换值,ruby-on-rails,ruby-on-rails-4,activerecord,Ruby On Rails,Ruby On Rails 4,Activerecord,场景 我的媒体可以有很多音轨,我想在媒体中存储音轨序列,但对于特定媒体,序列必须是唯一的。因此,例如,一个媒体对象可能有10个磁道,每个磁道的序列为1,2。。十, class Medium < ActiveRecord::Base has_many :tracks, inverse_of: :medium, dependent: :destroy end class Track < ActiveRecord::Base belongs_to :medium val
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
class-Medium
但是,用户可以更改轨迹序列,例如,他们将第二个轨迹移动到第8个位置-这将导致序列3-8的轨迹序列递减1(分别变为2-7),序列2的原始轨迹变为轨迹8
问题
问题是我不能简单地更改值并保存曲目,因为验证当然会失败
我能想到的唯一解决办法是:
media.save
的操作
Rails中是否有更好的实践来处理此场景,或者它是否像看上去那样复杂。将此视为一种特殊情况并以原子方式处理对序列的每次更改是否更好?这意味着一旦用户更改了曲目序列(调用父存储处理的其他曲目属性更改,即…media.save
)您可以在父媒体记录上使用a并执行所有更改,包括一个块中的序列重新编号。您可以在父媒体记录上使用a并执行所有更改,包括一个块中的序列重新编号。您可以使用来解决排序和重新排序问题
Gemfile
gem 'acts_as_list'
中等。rb
class Medium < ActiveRecord::Base
has_many :tracks,
-> { order(sequence: :asc) },
inverse_of: :medium,
dependent: :destroy
end
class Track < ActiveRecord::Base
belongs_to :medium
acts_as_list column: :sequence, scope: :medium
end
class-Medium{order(sequence::asc)},
介质的逆,
依赖::销毁
终止
track.rb
class Medium < ActiveRecord::Base
has_many :tracks,
-> { order(sequence: :asc) },
inverse_of: :medium,
dependent: :destroy
end
class Track < ActiveRecord::Base
belongs_to :medium
acts_as_list column: :sequence, scope: :medium
end
classtrack
您可以使用来解决排序和重新排序问题
Gemfile
gem 'acts_as_list'
中等。rb
class Medium < ActiveRecord::Base
has_many :tracks,
-> { order(sequence: :asc) },
inverse_of: :medium,
dependent: :destroy
end
class Track < ActiveRecord::Base
belongs_to :medium
acts_as_list column: :sequence, scope: :medium
end
class-Medium{order(sequence::asc)},
介质的逆,
依赖::销毁
终止
track.rb
class Medium < ActiveRecord::Base
has_many :tracks,
-> { order(sequence: :asc) },
inverse_of: :medium,
dependent: :destroy
end
class Track < ActiveRecord::Base
belongs_to :medium
acts_as_list column: :sequence, scope: :medium
end
classtrack
请详细说明这个答案。Save会自动包装在事务块中,如果我试图从控制台执行此操作,则会抛出验证错误-我添加了接受\u嵌套的\u属性\u for:tracks
,并调用medium。Save
以测试它。请详细说明此答案。Save自动包装在事务块中,如果我试图从控制台执行此操作,则会抛出验证错误-我添加了接受\u嵌套的\u属性\u for:tracks
,并调用medium.Save
对其进行测试。哦,这看起来很有希望。。。。等我有机会再打给你,我就得试试。谢谢:)顺便说一句。。你能编辑这个链接吗。。它坏了。。。只需要删除最后几个字符。工作完美,给了我确切的我需要的。。。对于您的解决方案,->{order(sequence::asc)},
必须在介质的逆之前出现。要使用我现有的数据库,我可以使用acts\u as\u list column::sequence,scope::medium
噢,这看起来很有希望。。。。等我有机会再打给你,我就得试试。谢谢:)顺便说一句。。你能编辑这个链接吗。。它坏了。。。只需要删除最后几个字符。工作完美,给了我确切的我需要的。。。对于您的解决方案,->{order(sequence::asc)},
必须在介质的逆之前出现。要使用现有数据库,我可以使用acts\u as\u list column::sequence,scope::medium