Rails无需数据库给模型添加自定义属性返回JSON报错如何解决
解决方案
报错的根本原因是Rails的ActiveRecord模型默认仅为数据库映射字段生成读写方法,未声明的自定义属性没有对应的custom_attribute= setter方法,无需修改数据库的前提下有三种常用实现方案:
方案1:使用Rails内置属性API(推荐,适配长期使用场景)
Rails 5及以上版本提供的属性API支持给模型声明非持久化的自定义属性,直接在模型中添加声明即可:
class Model_a < ApplicationRecord # 第二个参数指定属性类型,和数据库字段类型用法一致 attribute :custom_attribute, :integer end
声明后就可以正常对实例赋值custom_attribute,返回JSON时该属性会被自动序列化输出,无需额外修改控制器逻辑。
方案2:控制器层转哈希追加属性(适合临时一次性场景)
如果不想修改模型代码,仅需要在当前接口临时追加属性,可以直接把查询结果转成普通哈希后再修改:
class A_Controller < ApplicationController def index # 把所有实例转成可直接修改的哈希结构 @a_s = Model_a.all.map(&:as_json) @a_s[0]['custom_attribute'] = 777 json_response(@a_s) end end
这种方案不需要修改模型,对业务侵入性最低,适合仅在单个接口使用的自定义属性场景。
方案3:手动设置实例变量+指定序列化方法
如果需要保留ActiveRecord实例对象的其他方法调用能力,可以手动给实例注入实例变量,序列化时指定包含该属性即可:
# 模型中添加自定义属性的getter方法 class Model_a < ApplicationRecord def custom_attribute @custom_attribute end end
# 控制器中赋值并指定序列化时包含该方法 class A_Controller < ApplicationController def index @a_s = Model_a.all @a_s[0].instance_variable_set(:@custom_attribute, 777) json_response(@a_s.as_json(methods: :custom_attribute)) end end
内容的提问来源于stack exchange,提问作者Developer Cobra Kai Miguel
相关产品推荐
相关产品推荐

