如何在FactoryGirl工厂中正确定义模型别名属性以解决undefined method报错
报错原因
你在模型中仅使用alias customer_name full_name为**读方法(getter)**创建了别名,没有为对应的写方法(setter:full_name=)创建别名。ActiveModel::Model的初始化逻辑会遍历所有传入的属性,调用对应#{属性名}=方法完成赋值,你的工厂中定义了customer_name属性,初始化时会自动查找customer_name=方法,因此触发不存在的方法报错。
解决方案
提供三种可选方案,按推荐优先级排序:
方案1:模型层补全setter别名(推荐)
直接在User模型中同时为getter和setter加别名,后续业务代码也可以正常使用customer_name=赋值,无需修改现有工厂代码:
class User include ActiveModel::Model … alias customer_name full_name alias customer_name= full_name= # 新增该行,为setter方法创建别名 end
方案2:工厂层删除冗余的别名属性定义
因为你已经为读方法创建了别名,只要给full_name赋值,调用user.customer_name时会自动返回full_name的值,无需在工厂中单独定义customer_name属性:
FactoryGirl.define do factory :user do id { rand(83800..83999) } … full_name "My name" # 注意你原代码此处多了一个引号,存在语法错误,需修正 # 删除原有的customer_name定义行 skip_create initialize_with { new(attributes) } end end
修改后初始化传入的attributes中不会包含customer_name,不会触发setter查找逻辑。
方案3:工厂层过滤别名属性
如果你需要保留工厂中customer_name的定义,可以在初始化时过滤掉该属性,仅传入支持赋值的属性:
initialize_with { new(attributes.except(:customer_name)) }
该方案为临时兼容写法,可维护性较低,不建议长期使用。
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

