Ruby on rails 更改关联ID(而不是值)的多对一关联
我有一个Ruby on rails 更改关联ID(而不是值)的多对一关联,ruby-on-rails,associations,Ruby On Rails,Associations,我有一个用户模型,它属于:位置(即每个用户只能有一个位置,但一个位置可以由多个用户共享)。users表中有一个location\u id列来跟踪此信息 如果用户想要改变他们的位置,我相信Rails关联的默认行为是改变实际的关联;但是,在这种情况下,我希望现有的关联(即现有的位置记录)保持不变,并创建一个新的关联 例如,假设我们有用户Alice、Bob、Charley和Dave,他们都有location\u id==1,对应于芝麻街123号位置。然后,当Dave将其位置更改为芝麻街124号时,lo
用户
模型,它属于:位置
(即每个用户只能有一个位置,但一个位置可以由多个用户共享)。users
表中有一个location\u id
列来跟踪此信息
如果用户想要改变他们的位置,我相信Rails关联的默认行为是改变实际的关联;但是,在这种情况下,我希望现有的关联(即现有的位置
记录)保持不变,并创建一个新的关联
例如,假设我们有用户Alice、Bob、Charley和Dave,他们都有location\u id==1
,对应于芝麻街123号位置。然后,当Dave将其位置更改为芝麻街124号时,location
1不应受到任何影响或更改,应该使用新信息创建Location
2,并更新Dave的用户记录,以反映Location\u id
现在是2而不是1
我想在模型级别(大概是用户
模型)进行更改,这样,如果任何位置信息发生更改(用户
也接受:位置
的嵌套属性),则位置
关联将正确更新,而不会覆盖现有信息
有没有办法做到这一点,内置在Rails或插件中?
接受嵌套的属性\u 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\u 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
为
接受\u嵌套的\u属性\u创建一些用于处理嵌套表单的帮助器方法。在您的情况下,您需要覆盖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\u 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
Location
不仅仅是一个字段(它包含国家、州、城市、地址等),但这是一个有趣的见解-我不知道Location\u attributes=
方法。我在想,在保存之前,我必须以某种方式更改记录(例如使用find\u或
),但这可能是一个更好的主意!我能看到的唯一问题是,如果直接访问/更改user.location.attribute,该怎么办?有什么方法可以保护它吗?Location
不仅仅是一个字段(它有国家、州、城市、地址等),但这是一个有趣的见解-我不知道Location\u attributes=
方法。我在想,在保存之前,我必须以某种方式更改记录(例如使用find\u或
),但这可能是一个更好的主意!我能看到的唯一问题是,如果直接访问/更改user.location.attribute,该怎么办?有什么办法保护它吗?