Ruby on Rails update接口无法为post对象追加authorIds字段求助
问题描述
尝试将authorIds追加到post返回结构中,因Ruby开发经验不足,不确定实现方式。先后在post对象上调用merge、store等方法均未生效。
当前编写update接口时,获取当前用户关联的指定id的post记录后,尝试将请求传入的authorIds参数合并到post对象中,调用merge!、store等方法均失败;post.update(post_params)执行成功后,返回的JSON结构中也没有预期的authorIds字段,需要明确问题原因和正确实现方案。
现有实现代码:
def update post = current_user.posts.find_by(id: params[:id]) # postMap = {post: post} # post.merge!("authorIds": params[:authorIds]) # newPost = post.merge!('authorIds', params[:authorIds] if post.update(post_params) render json: {post: post}, status: :ok else render json: {error: post.errors}, status: :unprocessable_entity end end
相关参考:
- 路由方法截图
- 测试用例截图
问题原因
- 核心错误是混淆了Ruby普通Hash对象和ActiveRecord(AR)模型实例:
merge!、store都是Hash类的实例方法,post是AR模型对象,不是Hash,直接调用这两个方法本身就不符合方法调用规则,不可能生效。 - AR的
update方法只会更新对应数据库表中真实存在的字段,如果posts表没有author_ids字段,就算把参数传入update,默认的模型序列化结果也不会自带这个字段。
正确实现方案
根据authorIds的业务属性分两种场景处理:
场景1:authorIds是Post与Author的关联属性
如果Post和Author是多对多关联,不需要手动合并字段,按AR关联规则配置即可:
- 先在Post模型中声明关联
# app/models/post.rb class Post < ApplicationRecord # 假设多对多通过post_authors中间表关联 has_many :post_authors has_many :authors, through: :post_authors end
- 把
author_ids加入strong parameter白名单,注意数组类型参数的写法
def post_params params.require(:post).permit(:其他_post字段, author_ids: []) end
- 调整渲染逻辑,指定序列化时返回关联或关联id
def update post = current_user.posts.find_by(id: params[:id]) if post.update(post_params) # methods: :author_ids 会直接返回关联的作者id数组,也可以用include: :authors返回完整作者信息 render json: {post: post.as_json(methods: :author_ids)}, status: :ok else render json: {error: post.errors}, status: :unprocessable_entity end end
场景2:authorIds是不需要持久化的临时字段
如果authorIds不需要存入数据库,只是要在本次接口返回时额外追加,不要尝试修改AR对象本身,直接在序列化生成的Hash上合并字段即可:
def update post = current_user.posts.find_by(id: params[:id]) if post.update(post_params) # 先把AR对象转成Hash,再调用merge追加临时字段 post_data = post.as_json.merge(authorIds: params[:authorIds]) render json: {post: post_data}, status: :ok else render json: {error: post.errors}, status: :unprocessable_entity end end
注:Ruby中只有Hash对象可以直接调用
merge/merge!/store这类键值操作方法,操作AR对象时要优先用AR提供的属性赋值、关联操作接口,不要直接套用Hash的操作方法。
内容的提问来源于stack exchange,提问作者Jose Cantu
相关产品推荐
相关产品推荐

