当我使用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数组中删除,并且该数目从页面上消失,与预期的一样。
但是关联并不会在数据库中意外更新,并且当我重新加载页面时,该数字会重新出现。
答案 0 :(得分:0)
与普通的服务器端ActiveRecord API不同,您需要显式保存已删除的项目
issues.delete(issues_to_deassign).save
为什么?
问题在于删除项目意味着将进行数据库保存。
由于浏览器必须与服务器异步,因此Hyperstack对任何更新数据库的AR方法(例如,保存,更新,创建等)都返回一个承诺。然后,该承诺将在数据库更新完成时解决。
但是,期望delete
方法返回刚刚删除的对象,因此存在矛盾。
因此共有3种设计选择。
1.打破删除的工作方式,进行保存并返回承诺;
2.让delete进行保存,但不要承诺返回已删除的项目;
3.具有删除功能,返回项目,然后让开发人员明确地进行保存。 选项1和2不好,因为使删除操作不灵活。
选项3打破了ActiveRecord的标准语义,可以在需要时轻松实现这些语义(例如,通过在末尾添加save
),而不会牺牲灵活性