Rails数据库记录锁定:如何在数据播种时锁定指定Movie记录?
搞定电影记录锁定的完整方案
没问题,我来帮你实现这个需求——不用删除电影,而是标记锁定,同时限制对应的业务操作。分这几步来:
1. 先给Movie模型加锁定状态字段
首先得给你的Movie表加个布尔类型的字段,用来标记是否锁定。先跑迁移:
rails generate migration AddLockedToMovies locked:boolean
执行迁移:
rails db:migrate
然后在Movie模型里设置默认值,确保新创建的电影默认是未锁定的:
class Movie < ApplicationRecord # 你的其他模型代码... attribute :locked, default: false end
2. 修改种子文件的锁定逻辑
把原来删除电影的代码,改成批量更新锁定状态就好,用update_all效率很高:
require 'open-uri' @doc=Nokogiri::XML(open("http://www.kinoballada.info/repertuar/export/small/dzien/xml")) movie_array = [] @doc.css('dzien').each do |node| children=node.children movie_title = children.css('tytul').inner_text movie_array << movie_title # 找到或创建电影时,确保它是未锁定的 Movie.find_or_create_by(name: movie_title) do |movie| movie.locked = false end end # 锁定不在API返回列表里的电影 movies_to_lock = Movie.where.not(name: movie_array) movies_to_lock.update_all(locked: true)
3. 实现业务层面的限制
接下来要处理你提到的两个核心限制:
禁止为锁定电影创建话题
假设你的Topic模型关联了Movie,直接在Topic里加个验证就行:
class Topic < ApplicationRecord belongs_to :movie # 其他代码... validate :prevent_locked_movie_topics private def prevent_locked_movie_topics if movie&.locked? errors.add(:movie, "这个电影已经被锁定,不能创建话题哦") end end end
禁用锁定电影的show页面
在MoviesController的show动作里加判断,直接拦截访问:
class MoviesController < ApplicationController def show @movie = Movie.find(params[:id]) if @movie.locked? # 可以直接返回404页面,用户就看不到了 render file: "#{Rails.root}/public/404.html", status: :not_found, layout: false # 或者自定义一个锁定提示页面: # render :locked, status: :forbidden end end end
如果用自定义提示页面,记得在app/views/movies/下建个locked.html.erb,写点友好的提示,比如“抱歉,该电影已被锁定,无法访问详情”。
这样一套下来,就完美实现了你要的锁定效果啦!
内容的提问来源于stack exchange,提问作者Ins0maniac
相关产品推荐
相关产品推荐

