我正在开发一个Rails 5应用程序,其中遇到了以下困难。
我有两个型号,让我们说Kid
和Toy
,它们是这样的一对一关系:
class Kid < ActiveRecord::Base
has_one :toy
end
class Toy
belongs_to :kid, optional: true
end
因此toys
可以属于零或一kid
,而且每天都可以更改 - kid
负责照顾一个toy
某些toy
。现在,当我编辑kid
时,更改其kid_id
非常简单:我只需在强参数中发送params.require(:toy).permit(:name, :type, :kid_id)
即可更新记录:
params.require(:kid).permit(:name, :age, :toy_id)
但是最近,我被要求从其他方面实现更改功能,也就是说,在编辑孩子时,我应该这样做:
belongs_to
问题是 - 虽然association_id
适用于has_many
,甚至association_ids
提供has_one
getter和setter - has_one
关系也没有这样的结果。更重要的是,association = @record
关联会在我调用toy_id
时保存。所以我无法通过在强参数中发送@kid.update(kid_params); @kid.toy = @toy
来设置它。
我可以在控制器级别上执行类似toy
的操作,但这样可以将模型逻辑带到我的控制器,更不用说我想检查新分配的kid
是否属于另一个Kid
,我想这是一种验证。
我能想到的最好的方法是为def toy_id
@toy_id = toy.id unless defined?(@toy_id)
@toy_id
end
def toy_id_changed?
toy_id != toy.id
end
类定义一些类似于rails的方法,如
validation
并设置before_commit
和validate if: -> { toy_id.present? && toy_id_changed? } do
errors.add :toy_id, :other_has_it if new_toy.kid_id.present? && new_toy.kid_id != id
end
before_commit if: -> { toy_id_changed? } do
toy = new_toy
end
private
def new_toy
@new_toy ||= Toy.find(toy_id)
end
回调
toy_id
到目前为止,它按预期工作,现在我可以在强参数列表中发送kid
来更新toy
,并在以下时更新float
关联 -
并且只有 - 没有验证错误。我甚至把它关注得很好并且分开了。
我的问题是:是不是有铁路方式可以做到这一点?我没有重新发明轮子?
提前致谢!