在我的应用程序中,我有一个名为User的实体,其中有一个Talent。人才是用户可以在我的系统上(模型,摄影师,视频制作者,客户)的一种
#user.rb
class User < ApplicationRecord
has_one :talent, dependent: :destroy
人才属于用户,并且具有许多人才能力。
#talent.rb
class Talent < ApplicationRecord
belongs_to :user
has_many :talent_talent_abilities, dependent: :destroy
has_many :talent_abilities, through: :talent_talent_abilities
因此,我们可以创建例如属于Talent的TalentAbility。像这样:
TalentType.create!([
{name: "Model", is_model: true, is_photo: false, is_makeup: false, is_hair: false},
{name: "Photographer", is_model: false, is_photo: true, is_makeup: false, is_hair: false
])
TalentAbility.create!([
{name: "Scuba diving", requires_description: false, talent_type_id: 1}
{name: "River rafting", requires_description: false, talent_type_id: 1},
我想添加一个视图,该用户根据您的TalentType编辑自己的个人资料,并带有很多复选框,例如“ Scuba Diving-> true”。 “河漂流->错误”。
我的问题是:如何在我的控制器上更新这些关系的更好方法?首先删除属于该人才的所有TalentTalentAbility,然后根据我的表单添加所有人才?
#profiles_controler.rb
def update
##delete all the entities
TalentTalentAbility.where(talent: u.talent).each do |tt|
tt.destroy
end
##some code to add the new relationships
end
谢谢
答案 0 :(得分:1)
我过去做过类似的事情,而且效果很好。不过,我会将其移至模型中,因此您会遇到类似的情况。
class User < ActiveRecord::Base
ActiveModel::Dirty # if you need to track changes and only delete on attrs changed
before_save :update_talents
# ...
private
def update_talents
talents.destroy_all if talents_changed?
end
end
然后,新人才将与表格数据一起保存。而且,这样您的控制器就不会不必要地混乱。
但是,您应该小心以确保这是您想要的行为。您也可以添加检查以仅在使用ActiveModel::Dirty
更改人才的情况下进行更新。可能需要*_changed
方法上的语法check进行关联。
注意事项
我倾向于提倡这种方法,因为我的嵌套表单使用JS定位来重新排序其中的项目。可能有一个更明智的方法。
答案 1 :(得分:1)
接受的答案存在问题:
假设您有一个具有5个才能的用户,而他选择了自己已经学会了第六个。如果您采用致电.destroy_all
的方式,则会发生以下情况:
DELETE
语句发送到数据库INSERT
语句发送到数据库解决此问题的正确方法是使用相应的ID呈现复选框,并使用_destroy
(了解更多here)属性。
简而言之,如果您得到一个包含以下内容的哈希值(很抱歉,您可能需要从表单中获取哈希值,但现在手头没有任何东西可以给您提供AZ示例)像这样:
..., talent_talent_abilities_attributes: [
{id: 1, _destroy: true},
{id: nil, talent_ability_id: 1}
{id: 2, talent_ability_id: 2, some_attribute: "value"}
]
然后保存用户,ActiveRecord将:
DELETE
语句。INSERT
语句。id: 2
的功能是否有所更改,它可能会或可能不会发出UPDATE
语句。我建议您在rails console
中进行一些修改,以创建用户并使用嵌套的属性数组手动更新其功能(再次请参见上述链接,以了解更多信息),并观察其生成的SQL查询数量。如果您还有其他问题,请在此下方留下评论,或者创建一个单独的,更具体的问题(我将争取更多的空闲时间来准备示例,并提供包含实际代码的答案)。