Rails:无需定义has_many,能否一键创建并关联belongs_to关联?
解决belongs_to关联下创建关联模型后外键未自动更新的问题
你遇到的问题很典型:当多个模型通过belongs_to关联到Thing,但Thing中不定义反向has_many时,用build_thing创建Thing后,当前模型(比如Comment)的外键不会自动写入数据库。原因是Rails默认不会在这种情况下自动触发当前模型的保存操作,毕竟没有反向关联的提示。
下面给你几个更简便的实现方式:
方式一:用create_thing替代build_thing,一步关联+保存
create_thing是belongs_to关联提供的方法,它会直接创建并保存Thing对象,同时在内存中给@comment设置好thing_id,之后只需保存@comment就能完成关联:
if @comment.create_thing(thing_params) && @comment.save # 关联成功,Thing和Comment的关联已持久化 else # 查看错误信息:@comment.errors 或 @comment.thing.errors end
方式二:给belongs_to关联加autosave: true选项
在Comment模型的关联定义里加上autosave: true,这样Rails会自动处理关联对象保存后的外键更新,无需手动调用update:
class Comment < ActiveRecord::Base belongs_to :thing, autosave: true end
之后控制器里的代码就能简化成你最初的写法,保存Thing时会自动同步更新@comment的thing_id:
thing = @comment.build_thing(thing_params) if thing.save # 此时@comment的thing_id已经自动写入数据库 end
注意:这个选项会让每次保存Comment时都自动保存关联的Thing,如果你不需要这个全局行为,谨慎使用。
方式三:直接赋值+事务确保原子性
如果不想修改模型,也可以用事务包裹创建和关联操作,确保两个操作要么都成功要么都失败,代码更简洁:
begin ActiveRecord::Base.transaction do thing = Thing.create!(thing_params) @comment.update!(thing: thing) end # 关联成功 rescue ActiveRecord::RecordInvalid => e # 处理错误,e.record指向保存失败的模型(Thing或Comment) end
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

