在Hyperstack上,删除方法不会更新数据库中的has_many关系

时间:2019-09-07 04:22:51

标签: javascript ruby-on-rails ruby reactjs hyperstack

当我使用delete方法更新Hyperstack上的模型中的has_many关系时,该关联在数据库中未更新,并且该关联仅在前端侧被删除。

我已经在rails 5.1.7上安装了rails-hyperstack gem'edge'分支

在此代码的主要组件中,单击页面中的数字时将调用Agent#deassign(number)。

我正在尝试在此代码中的Agent#deassign(number)方法中使用delete方法来删除有问题的关联。

app \ hyperstack \ components \ main.rb

class Main < HyperComponent
  before_mount do
    @current_agent = Agent.first
  end

  render(UL) do
    @current_agent.issues.pluck(:number).each do |num|
      LI do
        num.to_s
      end
        .on(:click) do
          @current_agent.deassign(num)
        end
    end
  end
end

app \ hyperstack \ models \ issue.rb

class Issue < ApplicationRecord
  belongs_to :agent
end

app \ hyperstack \ models \ agent.rb

class Agent < ApplicationRecord
  has_many :issues

  def deassign(number)
    issue_to_deassign = issues.detect { |issue| issue.number == number }
    issues.delete(issue_to_deassign)
  end
end

app \ db \ schema.rb

...
  create_table "agents", force: :cascade do |t|
    t.string "email"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end
...
  create_table "issues", force: :cascade do |t|
    t.integer "number"
    t.integer "agent_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["agent_id"], name: "index_issues_on_agent_id"
  end

该问题已从前端的agent.issues数组中删除,并且该数目从页面上消失,与预期的一样。

但是关联并不会在数据库中意外更新,并且当我重新加载页面时,该数字会重新出现。

1 个答案:

答案 0 :(得分:0)

与普通的服务器端ActiveRecord API不同,您需要显式保存已删除的项目

issues.delete(issues_to_deassign).save
  

为什么?

  问题在于删除项目意味着将进行数据库保存。

  由于浏览器必须与服务器异步,因此Hyperstack对任何更新数据库的AR方法(例如,保存,更新,创建等)都返回一个承诺。然后,该承诺将在数据库更新完成时解决。

  但是,期望delete方法返回刚刚删除的对象,因此存在矛盾。

  因此共有3种设计选择。

  1.打破删除的工作方式,进行保存并返回承诺;
  2.让delete进行保存,但不要承诺返回已删除的项目;
  3.具有删除功能,返回项目,然后让开发人员明确地进行保存。   选项1和2不好,因为使删除操作不灵活。

  选项3打破了ActiveRecord的标准语义,可以在需要时轻松实现这些语义(例如,通过在末尾添加save),而不会牺牲灵活性