基于Rails开发协作故事应用的技术疑问
嘿,很高兴帮你搞定这个Rails协作故事应用的年龄段权限和出生日期验证问题!我会一步步带你实现需求~
1. 先搞定User模型的出生日期验证
首先得确保用户填写的出生日期是合法的,咱们在User模型里加验证逻辑:
# app/models/user.rb class User < ApplicationRecord # 先把你的关联关系写上(假设你已经配置好了) has_many :story_users has_many :stories, through: :story_users # 强制用户必须填写出生日期 validates :birth_date, presence: true # 自定义验证:出生日期不能是未来的日期 validate :birth_date_cannot_be_in_future private def birth_date_cannot_be_in_future if birth_date.present? && birth_date > Date.today errors.add(:birth_date, "不能是未来的日期哦") end end end
这样用户注册或更新资料时,必须填有效的出生日期,不会出现离谱的日期。
2. 给用户计算对应的年龄段分组
咱们需要一个方法,根据用户的出生日期算出他属于哪个分组(5-9岁/10-13岁/14-17岁/18+岁),直接加到User模型里:
# app/models/user.rb def age_group # 计算准确的年龄(考虑还没到当年生日的情况) age = Date.today.year - birth_date.year age -= 1 if Date.today < birth_date + age.years # 根据年龄匹配对应的分组 case age when 5..9 then '5-9岁' when 10..13 then '10-13岁' when 14..17 then '14-17岁' else '18+岁' end end
调用current_user.age_group就能直接拿到用户的分组啦。
3. 给Story模型加上年龄段标记
故事得有对应的年龄段属性,这样才能和用户的分组匹配。先跑个迁移加字段:
rails generate migration AddAgeGroupToStories age_group:string rails db:migrate
然后在Story模型里加验证,确保只能填咱们规定的分组:
# app/models/story.rb class Story < ApplicationRecord has_many :story_users has_many :users, through: :story_users # 定义合法的年龄段选项 VALID_AGE_GROUPS = ['5-9岁', '10-13岁', '14-17岁', '18+岁'] # 强制故事必须选合法的年龄段 validates :age_group, presence: true, inclusion: { in: VALID_AGE_GROUPS } end
这样创建故事时,必须选择正确的年龄段,避免乱填。
4. 控制故事的可见性:只给用户看匹配的故事
接下来就是核心需求啦——让current_user只能看到自己年龄段的故事。咱们在StoriesController里修改查询逻辑:
# app/controllers/stories_controller.rb class StoriesController < ApplicationController before_action :authenticate_user! # 确保只有登录用户能访问 def index # 只筛选和当前用户年龄段匹配的故事 @stories = Story.where(age_group: current_user.age_group) end def show @story = Story.find(params[:id]) # 如果用户访问的故事和自己年龄段不匹配,直接跳走并提示 unless @story.age_group == current_user.age_group redirect_to stories_path, alert: "你无权查看这个故事哦" end end # 创建故事的逻辑(可选:可以强制故事的年龄段和用户一致) def create @story = current_user.stories.build(story_params) # 如果不想让用户选年龄段,强制用当前用户的分组,就取消下面的注释 # @story.age_group = current_user.age_group if @story.save redirect_to @story, notice: "故事创建成功啦!" else render :new end end private def story_params # 根据你Story模型的实际字段调整permit的内容 params.require(:story).permit(:title, :content, :age_group) end end
这样用户打开故事列表时,只会看到适合自己年龄段的内容;如果手动输入URL访问不匹配的故事,也会被拦截。
小扩展:支持多年龄段访问(可选)
如果以后想让某些故事对多个年龄段开放,可以把Story的age_group改成数组类型(需要用PostgreSQL数据库),然后修改查询逻辑:
- 迁移文件改成
t.string :age_group, array: true, default: [] - 查询时用
@stories = Story.where("age_group @> ARRAY[?]", current_user.age_group)
这样一个故事就能属于多个分组啦。
内容的提问来源于stack exchange,提问作者Mikey_Gnote
相关产品推荐
相关产品推荐

