我有一个User
模型belongs_to :location
(即每个用户只能有一个位置,但多个用户可以共享一个位置)。 users
表格有一个location_id
列来跟踪此内容。
但是,如果用户想要更改其位置,我相信Rails关联的默认行为是更改实际关联;但是,在这种情况下,我希望现有的关联(即现有的Location
记录)保持不变,并且要创建一个新关联。
例如,假设我们有用户Alice,Bob,Charley和Dave,所有人都有location_id == 1
,对应地点123 Sesame St.然后当Dave将他的位置改为124 Sesame St.时,{不应以任何方式影响或更改{1}} 1,并且应使用新信息创建Location
2,并更新Dave的用户记录以反映Location
现在是2而不是1。
我想在模型级别进行更改(可能是location_id
模型),这样如果任何位置信息发生更改(User
也User
),{{1正确更新关联,而不覆盖现有信息。
有没有办法做到这一点,内置到Rails或插件?
答案 0 :(得分:1)
accepts_nested_attributes_for
创建了一些辅助方法来处理嵌套表单。在您的情况下,您将要覆盖setter。这应该可以帮到你。
class User
accepts_nested_attributes_for :location
def location_attributes= attrs
new_location = Location.where(attrs).first
new_location ||= Location.create attrs
self.location = new_location
end
end
在你的表格中有类似的东西
= f.fields_for :location do |lf|
.field
= lf.label :address
= lf.text_field :address
.field
= lf.label :city
= lf.text_field :city
一些注意事项:
@user.build_location
的调用。如果您的位置模型是单个字段,则可以使用虚拟属性
简化整个过程class User
def location_address= address
new_location = Location.find_or_create_by_address(address)
self.location = new_location
end
def location_address
location.address
end
end
在这种情况下,您只需要表单中的文本字段
= f.text_field :location_address