首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在ruby中对嵌套表单进行更新?

如何在ruby中对嵌套表单进行更新?
EN

Stack Overflow用户
提问于 2018-11-29 20:08:12
回答 2查看 162关注 0票数 1

在我的应用程序中,我有一个名为User的实体,它有一个人才。人才是一种用户可以在我的系统上(模型,摄影师,录像师,客户)

代码语言:javascript
复制
#user.rb

class User < ApplicationRecord
  has_one :talent, dependent: :destroy

人才属于用户,并且拥有许多TalentAbilities。

代码语言:javascript
复制
#talent.rb
class Talent < ApplicationRecord
  belongs_to :user
  has_many :talent_talent_abilities, dependent: :destroy
  has_many :talent_abilities, through: :talent_talent_abilities

例如,我们可以创建一个属于人才的TalentAbility。如下所示:

代码语言:javascript
复制
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,编辑他的个人资料,与许多复选框,他可以点击例如,“斯库巴潜水->真”。“河漂流->假”。

我的问题是:如何更好地在我的控制器上更新这些关系?首先删除属于此天赋的所有TalentTalentAbility,然后根据我的表单添加所有?

代码语言:javascript
复制
#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

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-29 20:17:48

我过去也做过类似的事情,而且效果很好。我会把它移到模型上,这样你就会有这样的东西。

代码语言:javascript
复制
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方法的语法。

警告

我倾向于提倡这种方法,因为我的嵌套表单使用JS定位来重新排序其中的项目。也许有一种更明智的方法。

票数 1
EN

Stack Overflow用户

发布于 2018-11-29 22:04:00

被接受的答案的问题:

假设你有一个拥有5种天赋的用户,而他选择了第六种技能。如果采用调用.destroy_all的方式,就会发生这样的情况:

  • 发送给DB的5条单独的、连续的DELETE语句
  • 发送给DB的6条单独的、连续的INSERT语句

解决此类问题的正确方法是呈现带有相应is的复选框,并使用_destroy ( render 这里)属性。

简而言之,如果您得到了一个散列(您可能需要在从表单中获得它之后清理它,对不起,但是我手头没有任何东西可以给您提供一个A示例),其中包含这样的内容:

代码语言:javascript
复制
..., 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查询。如果您有任何进一步的问题,请在下面留下评论,或者创建一个单独的、更具体的问题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53546783

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档