在 Hyperstack 上,删除方法不会更新数据库中的 has_many 关系
On Hyperstack, delete method doesn't update has_many relationship in database
当我在Hyperstack上的模型中使用delete方法更新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数组中删除,页面上的数字如期消失。
但是关联没有在数据库中意外更新,当我重新加载页面时该号码重新出现。
不同于普通的服务器端 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 (i.e. save, update, create, etc.) The promise will then resolve when the database update completes.
However the expectation is that the delete
method returns the object that was just deleted, thus we have a contradiction.
So there was 3 design choices.
1. Break how delete works, and do the save and return a promise;
2. Have delete do the save, but instead of a promise return the deleted item;
3. Have delete return the item, and let the developer do the save explicitly.
Options 1 and 2, are not good since the make the delete operation inflexible.
Option 3, while breaking the standard semantics of ActiveRecord allows those semantics to be easily implemented if desired (i.e. by adding save
to the end) without sacrificing flexibility
当我在Hyperstack上的模型中使用delete方法更新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数组中删除,页面上的数字如期消失。
但是关联没有在数据库中意外更新,当我重新加载页面时该号码重新出现。
不同于普通的服务器端 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 (i.e. save, update, create, etc.) The promise will then resolve when the database update completes.
However the expectation is that thedelete
method returns the object that was just deleted, thus we have a contradiction.
So there was 3 design choices.
1. Break how delete works, and do the save and return a promise;
2. Have delete do the save, but instead of a promise return the deleted item;
3. Have delete return the item, and let the developer do the save explicitly.
Options 1 and 2, are not good since the make the delete operation inflexible.
Option 3, while breaking the standard semantics of ActiveRecord allows those semantics to be easily implemented if desired (i.e. by addingsave
to the end) without sacrificing flexibility