Ruby/Rails 场景下如何正确处理kwargs,实现按需传参给ActiveRecord更新方法
方案说明
你提出的实现思路是正确的,只需要修正两处语法问题即可正常运行:
- Ruby 中 Hash 类型没有
append!方法,新增/覆盖键值对可以直接通过kwargs[:key] = value的方式操作,也可以用merge!批量合并 - 你写的
if判断缺少闭合的end,语法不合法
最简可维护实现
完全可以省略额外的tags变量,直接在kwargs中追加可选参数,代码如下:
def resolve(id:, tag_ids: nil, **kwargs) article = current_user.articles.find(id) # 仅当传入了非空的tag_ids时,才给kwargs追加tags参数 kwargs[:tags] = Tag.where(id: tag_ids) if tag_ids.present? article.update!(**kwargs) article end
这个实现完全满足你的需求:
- 仅当调用方传入了
tag_ids时才会修改文章的标签字段,未传值时完全不触碰该字段,也不会产生多余的数据库查询 - 逻辑清晰,没有冗余代码,后续要新增其他可选更新字段,只需要加对应的判断行即可
- 性能和可维护性都比你原来的回退赋值方案更好
可选优化(按需使用)
如果需要避免传入不存在的tag_ids导致标签被清空的问题,可以增加存在性校验:
def resolve(id:, tag_ids: nil, **kwargs) article = current_user.articles.find(id) if tag_ids.present? valid_tags = Tag.where(id: tag_ids) # 校验所有传入的tag_id都有效,按需开启 if valid_tags.count != tag_ids.uniq.size raise GraphQL::ExecutionError, "包含无效的标签ID" end kwargs[:tags] = valid_tags end article.update!(**kwargs) article end
内容的提问来源于stack exchange,提问作者Alien
相关产品推荐
相关产品推荐

