简体   繁体   English

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

[英]On Hyperstack, delete method doesn't update has_many relationship in database

When I use delete method to update a has_many relationship in a model on Hyperstack, the association is not updated in the database, and the association is deleted only on the front end side. 当我使用delete方法更新Hyperstack上模型中的has_many关系时,该关联在数据库中不会更新,并且该关联仅在前端侧被删除。

I have installed rails-hyperstack gem 'edge' branch, on rails 5.1.7 我已经在rails 5.1.7上安装了rails-hyperstack gem'edge'分支

In Main component in this code, Agent#deassign(number) is called when clicking the number in the page. 在此代码的主要组件中,单击页面中的数字将调用Agent#deassign(number)。

I am trying to use delete method in Agent#deassign(number) method in this code to delete the association with an issue. 我正在尝试在此代码中的Agent#deassign(number)方法中使用delete方法来删除有问题的关联。

app\\hyperstack\\components\\main.rb 应用程序\\超级堆栈\\组件\\ 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 应用\\超级堆栈\\模型\\ issue.rb

class Issue < ApplicationRecord
  belongs_to :agent
end

app\\hyperstack\\models\\agent.rb 应用程序\\超级堆栈\\模型\\ 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 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

The issue is deleted from the agent.issues array on the front end, and the number disappears from the page as expected. 该问题已从前端的agent.issues数组中删除,并且该数目从页面上按预期消失了。

But the association isn't updated in the database unexpectedly, and the number re-appears when I reload the page. 但是关联并不会意外地在数据库中更新,并且当我重新加载页面时该数字会重新出现。

Unlike the normal serverside ActiveRecord API you need to explicitly save the item that was removed 与普通的服务器端ActiveRecord API不同,您需要显式保存已删除的项目

issues.delete(issues_to_deassign).save

WHY? 为什么?

The problem is that deleting an item implies a database save will occur. 问题在于删除项目意味着将进行数据库保存。

Because the browser must be asynchronous with the server, Hyperstack returns a promise for any AR methods that update the database (ie save, update, create, etc.) The promise will then resolve when the database update completes. 由于浏览器必须与服务器异步,因此Hyperstack对任何更新数据库的AR方法(例如,保存,更新,创建等)都返回承诺,然后该承诺将在数据库更新完成时解决。

However the expectation is that the delete method returns the object that was just deleted, thus we have a contradiction. 但是,期望的是delete方法返回刚删除的对象,因此存在矛盾。

So there was 3 design choices. 因此,共有3个设计选择。

1. Break how delete works, and do the save and return a promise; 1.打破删除的工作方式,进行保存并返回承诺;
2. Have delete do the save, but instead of a promise return the deleted item; 2.让delete进行保存,但不要答应返回已删除的项目;
3. Have delete return the item, and let the developer do the save explicitly. 3.让delete返回该项,然后让开发人员明确地进行保存。

Options 1 and 2, are not good since the make the delete operation inflexible. 选项1和2不好,因为使删除操作不灵活。

Option 3, while breaking the standard semantics of ActiveRecord allows those semantics to be easily implemented if desired (ie by adding save to the end) without sacrificing flexibility 选项3打破了ActiveRecord的标准语义,可以在不牺牲灵活性的情况下轻松实现这些语义(例如,通过在最后添加save

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM